¿Devuelve todos los resultados dentro de un radio de 30 km de un punto específico de lat / long?

14

Tengo una tabla con una columna the_geom que contiene datos similares a:

0103000020E61000000100000005000000CE473AACFA071E40F27FB23340744740336FE841C6231E40873BED903F744740FC150A0ACE231E40D19E2684637647409C9B443D00081E409A9AF82664764740CE473AACFA071E40F27FB23340744740

Que al aplicar la función ST_AsEWKT(the_geom) devuelve:

SRID=4326;POLYGON((7.5077921782085 46.9082092877942,7.53493597966353 46.9081898840296,7.53496566473541 46.9249119938446,7.50781341296434 46.9249314035307,7.5077921782085 46.9082092877942))

Necesito seleccionar todos los datos que estén dentro de un radio de 30 km de un punto específico de lat / long, por ejemplo:

  • lat = 46.8167
  • lng = 6.9333

Sin embargo, cuando intenté usar ST_Distance() , siempre recibí valores menores a 1, y usar ST_DWithin() siempre devolvió verdadero.

    
pregunta dan2k3k4 11.11.2013 - 12:29

4 respuestas

17

Por favor revise la siguiente consulta de PostgreSQL para obtener datos dentro de cierta distancia. Espero que te ayude.

SELECT *
FROM your_table
WHERE ST_Distance_Sphere(the_geom, ST_MakePoint(your_lon,your_lat)) <= radius_mi * 1609.34
    
respondido por el Farhat Abbas 11.11.2013 - 13:24
6

Parece que estás almacenando tu geometría en una columna de geometría, no en una columna de geografía.
Eso está bien, pero la función ST_Distance devolverá las mediciones en unidades de proyección en lugar de siempre medidores. En su caso (4326), eso será en grados.
El solo uso de un búfer con ST_Within tampoco funcionará, ya que el ST_Buffer también se medirá con grados.

Puede convertir sus datos para usar geografía en lugar de geometría, o puede convertir su punto en una proyección que use medidores, búfer, y luego volver a convertir a 4326 para ver qué contiene:

SELECT
    *
FROM <your data>
WHERE ST_Within(the_geom, 
                ST_Transform(ST_Buffer(ST_Transform(ST_SetSRID(ST_MakePoint(6.9333, 46.8167), 4326), 3857), 30000), 4326)) = 1

Eso proyecta el punto en 3857 , que es una proyección popular entre los mapas web . Luego lo amortigua por 30,000 metros y luego lo reproyecta a 4326 antes de pasarlo a ST_Within.

    
respondido por el Evil Genius 11.11.2013 - 13:30
5

En mi mundo, usar un SRID personalizado (para Google Maps) algo como esto funcionó:

SELECT * FROM addresses WHERE ST_DWithin(location, ST_SetSRID(ST_MakePoint(longitude, latitude), 3785), radius);

donde el tipo de location es una geometría (Punto, 3785), y longitude , latitude y radius son flotantes (por ejemplo, -100, 44, 30 para unidades de 100W / 44N / 30 " "- ver más abajo)

Consulte ¿Cuál es la mejor manera de encontrar todos los objetos dentro de un radio de otro objeto? en los documentos postgis:

  

La función ST_DWithin(geometry, geometry, distance) es una forma útil de realizar una búsqueda de distancia indexada. Funciona al crear un rectángulo de búsqueda lo suficientemente grande como para incluir el radio de la distancia, y luego realizar una búsqueda de distancia exacta en el subconjunto indexado de resultados.

ACTUALIZACIÓN: las unidades no son millas para SRID 3785 ... parecen ser radianes o grados o algo así. Pero la especificación para mi SRID dice que sus unidades son metros o grados y definitivamente no es ninguna de esas, al menos no sin una conversión:

alex=# select * from spatial_ref_sys where srid=3785; srid | auth_name | auth_srid | srtext | proj4text
3785 | EPSG | 3785 | PROJCS["Popular Visualisation CRS / Mercator (deprecated)",GEOGCS["Popular Visualisation CRS",DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137,0,AUTHORITY["EPSG","7059"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6055"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4055"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m [email protected] +wktext +no_defs"],AUTHORITY["EPSG","3785"],AXIS["X",EAST],AXIS["Y",NORTH]] | +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m [email protected] +wktext +no_defs

    
respondido por el AlexChaffee 14.10.2014 - 20:45
0

Creo que esto debería funcionar:

SELECT gid FROM table 
WHERE ST_DWithin(the_geom, ST_SetSRID(ST_Point(6.9333, 46.8167), 4326), 30000)
    
respondido por el Francisco Puga 11.11.2013 - 13:24

Lea otras preguntas en las etiquetas