我是PostgreSQL和PostGIS的新手。我想在PostgreSQL 9.1.1数据库表中存储纬度和经度值。我将计算两点之间的距离,通过使用这个位置值找到更近的点。

我应该为纬度和经度使用哪种数据类型?


当前回答

你可以使用数据类型point - combine (x,y),它可以是你的lat / long。占用16字节:内部2个float8数字。

或者将其设置为float类型的两列(= float8或double precision)。每个8字节。 如果不需要额外的精度,则为real (= float4)。每个4个字节。 如果你需要绝对的精度,甚至是数字。每组4个数字2个字节,外加3 - 8个字节的开销。

阅读关于数字类型和几何类型的详细手册。


几何和地理数据类型由附加模块PostGIS提供,并在表中占据一列。每个点占用32个字节。这里有一些额外的开销,比如SRID。这些类型存储(long/lat),而不是(lat/long)。

从这里开始阅读PostGIS手册。

其他回答

如果你不需要PostGIS提供的所有功能,Postgres(现在)提供了一个名为earthdistance的扩展模块。它使用点或立方体数据类型,这取决于您对距离计算的精度需求。

您现在可以使用earth_box函数来查询距离某个位置一定距离内的点。

使用点数据类型将经度和纬度存储在单个列中:

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)
)

在'location'列上创建索引:

CREATE INDEX ON table_name USING GIST(location);

GiST索引能够优化“最近邻”搜索:

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

注意:点的第一个元素是经度,第二个元素是纬度。

有关更多信息,请查看此查询操作符。

在PostGIS中,几何学比地理学(圆形地球模型)更受欢迎,因为计算更简单,因此更快。它也有很多可用的功能,但在很长的距离上精度较低。

将您的CSV长和长字段导入到DECIMAL(10,6)列。6位是10cm的精度,对于大多数用例来说应该足够了。然后将导入的数据转换为正确的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);

在PostGIS中,对于具有纬度和经度的点,有地理数据类型。

添加一列:

alter table your_table add column geog geography;

插入数据:

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

4326是空间参考ID,表示它是以度、经度和纬度为单位的数据,与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;

我强烈支持PostGis。它是特定于这种数据类型的,它有开箱即用的方法来计算点之间的距离,以及其他GIS操作,您将来会发现这些操作很有用