问题
I'm using postgresql as db , i have the table named car_wash with field "point geometry"(use postgis) so in application I'm getting lon lat from user using GOOGLE API, next step I need to create circle around user and check if car_wash inside this circle I use
select *
from car_wash cw
where
ST_DWithin (
cw.lon_lat,
ST_GeomFromText('POINT(54.21 22.54)')
)=false
AND
not cw.was_deleted
Is it corect way? IF you need my srid is 0 according to this query
Select Find_SRID('public', 'car_wash', 'lon_lat')
回答1:
SRID of the ST_GeomFromText('POINT(54.21 22.54)') must be same as the SRID of cw.lon_lat. Suppose SRID of cw.lon_lat is 4326 you can set the other attribute srib by using ST_GeomFromText('POINT(54.21 22.54)',4326). Secondly, ST_DWithin needs buffer distance as 3rd parameter. So suppose if you want to check if point is within 100 meter buffer it should be like
ST_DWithin (
cw.lon_lat,
ST_GeomFromText('POINT(54.21 22.54)', 3857), 100
)
Buffer value is according to the srid unit. in case of 3857 its meter. You need to convert cw.lon_lat and POINT(54.21 22.54) to the same SRID in order to make this work, using st_setSRID e.g.
回答2:
While using ST_DWithin
function, your third parameter must be distance.
You can also define srid in ST_GeomFromText
there are two simple example so you can see difference:
select ST_DWithin(
st_geomfromtext('POINT(54.51 22.54)',4326),
st_geomfromtext('POINT(54.21 22.54)',4326),0.5
)
result is true
select ST_DWithin(
st_geomfromtext('POINT(54.51 22.54)',4326),
st_geomfromtext('POINT(54.21 22.54)',4326),0.1
)
result is false
Source:
https://postgis.net/docs/ST_DWithin.html
http://postgis.org/docs/ST_GeomFromText.html
回答3:
First - i assume that lat_long is georaphy type column. If it is geometry type column you will have to modify my examples to some other EPSG (propably 3857 metric EPSG for whole world). It is very important because st_dwithin check in meters for geopraphy type , and in map units for geometry (and for EPSG 4326 unit is degree not meter)
Insert your data like this
insert into car_wash values (1,'aaa',st_setsrid(st_makepoint(54.51, 22.54),4326))
I explain why use st_setsrid, st_makepoint, and what the hell is 4326. - 4326 is EPSG 4326 - it is most known coordinate reference system (where you have lat and long in degrees).
st_makepoint - will create geography point from your lat and long coordinates. It will looks like bytes, but dont worry, if you will need lat and long for some reasons you can get them with st_x() and st_y() or st_astext() functions. Best thing of have geoms or geogs (in this case) is that you can use gist index. Very powerful tool that speed up your geo queries.
st_setsrid - st_makepoint will create point but with srid=0. You have to tell POSTGIS in what EPSG it should read your data. For example if you tell him to read it with 4326 it will be in correct places on google world map, but if you say for example 3857 it will be in completly diffrent place, as 3857 is metric system not degree so it will be around 50 and 50 meters from left down corner (or maybe left up, dont remember)
Create index on geog
create index on car_wash using gist (geog);
We have table, we have data in it and index on it. Now we want to check if your point is close to any of your car washes.
select *
from car_wash cw
where ST_DWithin (cw.geog,ST_GeogFromtext('SRID=4326;POINT(54.21 22.54)'),1000)
AND cw.was_deleted=false
In ST_DWithin third parameters is distance in meters (georpahy) or map units (geometry). So in this case it will show you all car washes that are up to 1000 meters from your user location and are not deleted.
来源:https://stackoverflow.com/questions/44450016/postgresql-postgis-if-point-inside-circle