Sqlalchemy: широта и долгота Точность поплавка? - PullRequest
11 голосов
/ 07 июля 2011

Я использую Sqlalchemy для определения своих таблиц и тому подобного, и вот код, который я придумал:

locations = Table('locations', Base.metadata,
Column("lat", Float(Precision=64), primary_key=True),
Column("lng", Float(Precision=64), primary_key=True),
)

Я читаю где-то , что широта и долгота требуют большей точности, чемплавает, как правило, с двойной точностью.Итак, я установил точность вручную на 64, это достаточно?Overkill?Поможет ли это даже моей ситуации?

Ответы [ 3 ]

6 голосов
/ 10 февраля 2015

Никто здесь не предоставил конкретные числа с доказательством точности наихудшего случая с плавающей запятой широта / долгота. Мне нужно было знать это для чего-то, над чем я работаю, так что вот мой анализ на случай, если он кому-то поможет.

Плавающая точка одинарной точности предлагает 24-битную точность в значенииand (двоичная экспоненциальная запись числа). Поскольку вся часть числа становится больше, число битов после десятичной дроби уменьшается. Следовательно, наихудшая точность для широты или долготы - это когда величина настолько далеко от 0, насколько это возможно. Предполагая, что вы привязали свои широты к [-90, 90] и долготы от (-180, 180], наихудший случай будет на экваторе для долготы 180.

В двоичном формате 180 требует 8 битов из 24 доступных битов, оставляя 16 бит после десятичной точки. Следовательно, расстояние между последовательно представленными значениями на этой долготе будет 2 ^ -16 град (приблизительно 1,526E-5). Умножение этого числа (в радианах) на радиус Земли WGS-84 на экваторе (6 378 137 м) дает наихудшую точность:

2^-16 deg * 6,378,137 m * PI rad / 180 deg = 1.6986 m (5.5728 ft).

Тот же анализ по широте / долготе, хранящимся в радианах, дает следующее:

2^-22 rad * 6,378,137 m = 1.5207 m (4.9891 ft)

И, наконец, если вы нормализуете широты в диапазоне [-1, 1] и долготы в диапазоне (-1, 1], то вы можете достичь следующей точности худшего случая:

2^-24 * PI rad * 6,378,137 m = 1.1943 m (3.9184 ft)

Таким образом, хранение широты / долготы в радианах дает вам около 7 дюймов дополнительной точности, а хранение их в нормализованной форме дает вам дополнительную точность порядка 1'8 ", как в худшем случае.

Если при преобразовании между двойной точностью и одинарной точностью вы округлили (вместо усечения), значение одинарной точности будет в пределах половины расстояния между двумя последовательными значениями, вычисленными выше.

4 голосов
/ 07 июля 2011

Это зависит от того, для чего вы используете свои данные.Если вы используете поплавок, все будет в порядке, если вам понадобится только уровень детализации до метра.Использование данных в графических приложениях вызовет эффект дрожания, если пользователь увеличит расстояние.Подробнее о джиттере и см. Точности, Точности .Надеюсь, это поможет.

2 голосов
/ 17 апреля 2013

Обновление : ответ Джеффа имеет лучший анализ. Однако ...

Чтобы улучшить ответ Джеффа:

Если вы поделите фактический угол в радианах на π, таким образом кодируя угол по шкале от 0 до ± 1, тогда можно будет использовать все цифры значащих и (23 бита (24 - 1 знаковый бит) )). Точность будет тогда:

2^-23 * 6,378,137 m = 0.7603 m (76 cm)

Мой старый ответ:

32-разрядное число с плавающей запятой может представлять число с точностью около 7,2 десятичных знаков. Это приблизительное значение, поскольку число с плавающей запятой на самом деле является двоичным, а при преобразовании в десятичное число число значащих цифр может варьироваться.

Если мы примем это как 6 десятичных цифр точности (чтобы играть на всякий случай), и если мы будем хранить широту и долготу в градусах, то мы получим точность около 1/1000-й степени, что является точностью около 111 метров в худшем случае. В лучшем случае, если мы получим 7 десятичных знаков точности, точность будет около 11,1 метра.

Можно получить лучшую точность, используя радианы в качестве единицы измерения. В худшем случае мы получаем точность в 10 миллионов радиан, что составляет около 63 метров. В лучшем случае это будет 1 миллионная часть радиана, что составляет около 6 метров.

Излишне говорить, что 64-битное число с плавающей запятой будет чрезвычайно точным (в худшем случае около 6 микрометров).

...