简体   繁体   中英

Get metric distance between two points via a PostgreSQL/PostGIS request

I have a question about the use of postgreSQL/postGIS.

I would like to display markers on a map (stored in a database) which are some distance away from the user (coordinates given to the request).

The type of the field of the markers is POINT (I store lat/long). The user position is detetermined by the Google Map API.

Here is the actual request :

SELECT * FROM geo_points WHERE ST_distance(ST_SetSRID(geo_points.coords::geometry,4326),ST_GeomFromEWKT('SRID=4326;POINT(45.0653944 4.859764599999996)')) > 65

I know (after some research on internet) that the function ST_distance gives me the distance in degree between markers and the user position and that I test the distance in km.

I think I have to use the function ST_tranform to transform the points in metric coordinates.

So my questions are : - what is the SRID for France - how can I make this dynamically for the entire world according to the user position ?

I also kow that the function ST_within exists and that could do this. But I anticipate the fact that later, I could need the distance.

Any help would be greatly appreciated

ps: there are maybe solutions in other post, but all the answers I have found during my researches were not really meeting my needs.

Firstly, pay attention to the axis order of coordinates used by PostGIS, it should be long/lat. Currently you are searching in Somalia . Swapping to the coordinates, you would be searching in France .

You can use a geodesic calculation with the geography type , or use geodesic functions like ST_Distance_Spheroid . With the geography type, you may want to use ST_DWithin for higher performance.

Here are geo_points 65 m away or less from the point of interest in France (not Somalia):

SELECT * FROM geo_points
WHERE ST_Distance_Spheroid(
    ST_Transform(geo_points.coords::geometry, 4326),
    ST_SetSRID(ST_MakePoint(4.859764599999996, 45.0653944), 4326),
    'SPHEROID["WGS 84",6378137,298.257223563]') < 65.0;

However, it will be very slow, since it needs to find the distance to every geo_points, so only do this if you don't care about performance and have less than a few thousand points.

If you change and transform geo_points.coords to store lon/lat (WGS84) as a geography type:

SELECT * FROM geo_points
WHERE ST_DWithin(
    geo_points::geography,
    ST_SetSRID(ST_MakePoint(4.859764599999996, 45.0653944), 4326)::geography,
    65.0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM