postgresql postgis If point inside circle

こ雲淡風輕ζ 提交于 2019-12-11 04:53:13

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!