Какой тип данных для широты и долготы?

Я новичок в PostgreSQL и PostGIS. Я хочу сохранить значения широты и долготы в таблице базы данных PostgreSQL 9.1.1. Я рассчитаю расстояние между двумя точками, найду более близкие точки, используя эти значения местоположения.

Какой тип данных следует использовать для широты и долготы?


person user1008404    schedule 16.11.2011    source источник
comment
Если вы делаете две точки (2D-карта широты и долготы), я бы использовал тип данных Geometry. Если вам нужно указать высоту или кривизну земли в ваших расчетах расстояния, география - это то, что вам нужно.   -  person Twelfth    schedule 08.12.2011
comment
Был ли какой-либо из ответов ниже на ваш вопрос? Если да, то советую выбрать один в качестве ответа :)   -  person Volte    schedule 24.04.2017


Ответы (6)


Вы можете использовать тип данных point - объединяет (x,y), которые могут быть вашими широтой и долготой. Занимает 16 байтов: 2 float8 числа внутри.

Или сделайте два столбца типа float (= float8 или double precision). По 8 байтов.
Или real (= float4), если дополнительная точность не требуется. По 4 байта.
Или даже numeric, если вам нужна абсолютная точность. 2 байта для каждой группы из 4 цифр плюс 3-8 байтов служебных данных.

Прочтите прекрасное руководство по числовым типам и геометрические типы.


Файлы geometry и geography предоставляются дополнительным модулем PostGIS и занимают один столбец в вашей таблице. Каждая точка занимает 32 байта. Есть некоторые дополнительные накладные расходы, такие как SRID. Эти типы хранят (долгота / широта), а не (широта / долгота).

Начните читать руководство по PostGIS здесь.

person Erwin Brandstetter    schedule 16.11.2011
comment
Я бы не рекомендовал использовать тип данных float. Это очень усложняет расчет с координатами. Для таких расчетов следует использовать PostGIS и тип данных geography. - person m13r; 19.12.2016
comment
Это действительно прекрасное руководство, не так ли? Яркий пример в документации. - person otocan; 17.11.2017
comment
Было бы быстрее сохранить long, lat и geog, вместо того, чтобы пытаться разобрать geog для исходной длинной широты? - person Dan; 02.05.2018
comment
@ Дэн: Зависит. Пожалуйста, задайте новый вопрос с подробностями. Вы всегда можете ссылаться на этот для контекста. Комментарии - не место для новых вопросов. - person Erwin Brandstetter; 04.05.2018

В PostGIS для точек с широтой и долготой существует тип данных geography.

Чтобы добавить столбец:

alter table your_table add column geog geography;

Чтобы вставить данные:

insert into your_table (geog) values ('SRID=4326;POINT(longitude latitude)');

4326 - это идентификатор пространственной привязки, в котором указаны данные в градусах долготы и широты, как и в GPS. Подробнее об этом: http://epsg.io/4326.

Порядок - это долгота, широта - поэтому, если вы построите его как карту, это будет (x, y).

Чтобы найти ближайшую точку, вам нужно сначала создать пространственный индекс:

create index on your_table using gist (geog);

а затем запросите, скажем, 5 ближайших к заданной точке:

select * 
from your_table 
order by geog <-> 'SRID=4326;POINT(lon lat)' 
limit 5;
person Darafei Praliaskouski    schedule 20.11.2017
comment
Уточнение: SRID 4326 хочет, чтобы широта и долгота были в таком порядке. Но интерпретация SRID 4326 в PostGIS требует, чтобы широта и долгота находились в таком порядке. Пример подходит для использования PostGIS. postgis.net/2013/08/18/tip_lon_lat - person hahmed; 29.06.2019
comment
ВЫБРАТЬ * ИЗ имя_таблицы ORDER BY location ‹-› point '(-74.013, 40.711)' LIMIT 10; здесь первый элемент точки - долгота, а второй элемент - широта - person Irshad Khan; 10.09.2020

Я настоятельно рекомендую PostGis. Он специфичен для такого типа данных и имеет готовые методы для расчета расстояния между точками, среди других операций ГИС, которые вы можете найти полезными в будущем.

person tvieira    schedule 27.01.2016

Если вам не нужны все функции, предлагаемые PostGIS, Postgres (в настоящее время) предлагает модуль расширения под названием earthdistance. Он использует точку или cube в зависимости от вашей точности, необходимой для расчета расстояния.

Теперь вы можете использовать функцию earth_box, например, для запроса точек на определенном расстоянии от местоположения.

person Hans Bouwmeester    schedule 19.11.2018

В PostGIS геометрия предпочтительнее географии (круглая модель земли), потому что вычисления намного проще, а значит, быстрее. Он также имеет МНОЖЕСТВО доступных функций, но менее точен на очень больших расстояниях.

Импортируйте поля длинного и широтного формата CSV в DECIMAL(10,6) столбец. 6 цифр - это точность 10 см, этого должно хватить для большинства случаев использования. Затем передайте импортированные данные в правильный SRID.

Неправильный путь!

/* try what seems the obvious solution */
DROP TABLE IF EXISTS public.test_geom_bad;
-- Big Ben, London
SELECT ST_SetSRID(ST_MakePoint(-0.116773, 51.510357),4326) AS geom
INTO public.test_geom_bad;

ПРАВИЛЬНЫЙ способ

/* add the necessary CAST to make it work */
DROP TABLE IF EXISTS public.test_geom_correct;
SELECT ST_SetSRID(ST_MakePoint(-0.116773, 51.510357),4326)::geometry(Geometry, 4326) AS geom
INTO public.test_geom_correct;

Убедитесь, что SRID не равен нулю!

/* now observe the incorrect SRID 0 */
SELECT * FROM public.geometry_columns
WHERE f_table_name IN ('test_geom_bad','test_geom_correct');

Проверьте порядок вашего параметра долгой широты с помощью средства просмотра WKT и

SELECT ST_AsEWKT(geom) FROM public.test_geom_correct

Затем проиндексируйте его для лучшей производительности

CREATE INDEX idx_target_table_geom_gist
    ON target_table USING gist(geom);
person golfalot    schedule 08.03.2020
comment
менее точен на очень больших расстояниях. Не могли бы вы упомянуть, что вы подразумеваете под словом «большое расстояние». Я читал это во многих блогах, но, не имея реального диапазона того, что считается большим расстоянием, мне трудно понять, что использовать. - person GCQ; 10.12.2020
comment
@GCQ Я предлагаю здесь оптимальный подход: вы взяли бы несколько образцов своих геоданных и измерили расстояния сами, используя геометрию один раз, а затем географию и сравнили результаты. Это связано с тем, что точность систем координат (проекций) зависит от географического положения. - person golfalot; 11.12.2020
comment
select st_point(12.0, 42.0)::geometry(Geometry, 4326) дает ОШИБКУ: SRID геометрии (0) не соответствует SRID столбца (4326), но select ST_SetSRID(ST_Point(12.0, 42.0),4326) работает ¯_ (ツ) _ / ¯ - person mathieu; 16.02.2021
comment
@mathieu, спасибо, что указали на это. Я исправил и улучшил ответ, чтобы лучше подчеркнуть риск неправильной установки SRID. - person golfalot; 17.02.2021

Используйте тип данных Точка, чтобы сохранить долготу и широту в одном столбце:

CREATE TABLE table_name (
    id integer NOT NULL,
    name text NOT NULL,
    location point NOT NULL,
    created_on timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT table_name_pkey PRIMARY KEY (id)
)

Создайте индексирование для столбца "местоположение":

CREATE INDEX ON table_name USING GIST(location);

Индекс GiST позволяет оптимизировать поиск «ближайшего соседа»:

SELECT * FROM table_name ORDER BY location <-> point '(-74.013, 40.711)' LIMIT 10;

Примечание. Первый элемент точки - это долгота, а второй - широта.

Для получения дополнительной информации см. Операторы запроса < / а>.

person Irshad Khan    schedule 10.09.2020