查询PostGIS半径给我奇怪的结果

时间:2018-10-24 16:21:08

标签: postgresql postgis

我是PostGIS的新手,正在尝试创建半径查询。我有一个带有geometry字段(位置)的表,并且在单独的字段上也有纬度和经度值。

我正试图在距拉特(lat):40.753777,lon(-73.981568)半径10公里处寻找点。

具有:

SELECT postcode, lat, lon, st_asgeojson(position) geojson, ST_Distance(ST_MakePoint(lat, lon), ST_MakePoint(40.753777, -73.981568)) distance FROM addresses WHERE ST_DWithin(ST_MakePoint(lat, lon), ST_MakePoint(40.753777, -73.981568), 10000) order by id limit 10;

结果给了我很远的一点。使用lat和lon进行的地球距离相同的查询直接为我提供了更接近的结果。

SELECT postcode, lat, lon, st_asgeojson(position) geojson FROM addresses WHERE earth_box(ll_to_earth(40.753777, -73.981568), 10000) @> ll_to_earth(addresses.lat, addresses.lon) order by id limit 10;

但是我真的也不知道这是否正确,PostGIS查询怎么了?

1 个答案:

答案 0 :(得分:0)

一些注意事项:

  1. 我认为您在定点时交换了纬度和经度,您的行显示为ST_MakePoint(40.753777,-73.981568),但定义是:
geometry ST_MakePoint(double precision x, double precision y);
Note: x is longitude and y is latitude

所以应该是ST_MakePoint(-73.981568,40.753777)。

  1. 作为一个简单的解决方案,您可以使用ST_Distance_Spheroid函数(http://www.postgis.org/docs/ST_Distance_Spheroid.html):
SELECT
    postcode, lat, lon, st_asgeojson(position) AS geojson,
    ST_Distance_Spheroid(
        position,
        ST_GeomFromText('POINT(-73.981568 40.753777)',
        4326), 'SPHEROID["WGS 84",6378137,298.257223563]'
    ) as distance
FROM addresses 
WHERE distance < 10000 LIMIT 10;
  1. 要获得更精确的距离,请从您现有的几何类型列position中添加一个新的geographic类型列:
ALTER TABLE addresses ADD COLUMN position_geog geography(Point,4326);
UPDATE addresses SET position_geog = position::geography;
CREATE INDEX ON addresses USING gist(position_geog);
-- and now you can use ST_DWITHIN with meters...