2011-02-24 9 views
7

Estoy tratando de hacer una consulta de orden que encuentre registros más cercanos al usuario_actual.Ordenar por más cercano - PostGIS, GeoRuby, spatial_adapter

sé la distancia entre los dos puntos es: current_location.euclidean_distance(@record.position)

¿Cómo puedo trabajar esto en una consulta PostGIS (o active_record/spatial_adapter)?

Respuesta

14

Para llegar la 5 más cercano:

SELECT * FROM your_table 
ORDER BY ST_Distance(your_table.geom, ST_Geomfromtext(your point as wkt)) 
limit 5; 

Si usted tiene un gran conjunto de datos y saber que no desea buscar más allá de, digamos 1 km, la consulta será más eficiente si lo hace:

SELECT * FROM your_table 
WHERE ST_DWithin(your_table.geom, ST_Geomfromtext(your point as wkt, 1000) 
ORDER BY ST_Distance(your_table.geom, ST_Geomfromtext(your point as wkt)) 
limit 5; 

/Nicklas

+0

Tengo mi posición en un método auxiliar ubicación_actual. ¿Sabes si es posible insertar esto en la consulta (rieles)? Algo así como: '.order ('ST_Distance (items.position, # {current_location})')' – DanS

+0

El problema fue que necesitaba doble quoates. '.order (" # current_location ")' – DanS

+1

Falta un corchete en la línea WHERE después de 'su punto como wkt' – DanS

1

Mire la documentación de ST_Distance en PostGIS.

0

Si usted no necesita utilizar PostGIS, geo-kit hace esto a la perfección a través de Google o Yahoo (sólo he utilizado Google) y en las consultas se pueden ordenar por distancia, es increíble ..

+1

tiene usted razón, pero se encuentra restringido por límite de solicitudes de Google por su API. en este caso es 2500 solicitud/24 horas – dc10

2

Para terminar con esto, con la ayuda de todos lo tengo trabajando como quería:

order("ST_Distance(items.position, ST_GeomFromText('POINT (#{current_location.y} #{current_location.x})', #{SRID}))") 
2

Si realmente quiere encontrar literalmente los 5 registros más cercanos a la current_user, considere búsqueda local, que es apoyado por el índice KNN en PostGIS 2.0 (ver '< ->' operador):

SELECT * FROM your_table ORDER BY your_table.geom < -> ST_GeomFromText (su punto como wkt, 1000) LIMIT 5

Suyo, S.

5

Sólo en caso de que alguien se tropieza con este problema en los carriles 4. que estoy usando joya RGEO y esto funciona para mí

scope :closest, ->(point) { order("ST_Distance(lonlat, ST_GeomFromText('# {point.as_text}', #{SRID}))").limit(5) } 
+1

debe agregar a la respuesta cómo se define el 'lonlat' en Rails/rgeo – Tilo

+3

Para otros novatos como yo, puede ser útil saber que el valor de' SRID' debe ser un entero que apunta a la ID universalmente conocida del sistema de coordenadas que está utilizando para calcular distancias. Probablemente estés buscando utilizar el [Sistema de coordenadas geodésicas] (https://en.wikipedia.org/wiki/World_Geodetic_System#WGS84) del planeta Tierra que es ID ** 4326 **. – sameers