Dada una base de datos de lugares con ubicaciones de latitud + longitud, como 40.8120390, -73.4889650, ¿cómo puedo encontrar todas las ubicaciones dentro de una distancia determinada de una ubicación específica?
No parece muy eficiente seleccionar todas las ubicaciones de la base de datos y luego revisarlas una por una, obteniendo la distancia desde la ubicación de inicio para ver si están dentro de la distancia especificada. ¿Existe una buena manera de reducir las ubicaciones seleccionadas inicialmente de la base de datos? Una vez que tengo (¿o no?) Un conjunto reducido de ubicaciones, ¿todavía las reviso una por una para verificar la distancia, o hay una mejor manera?
El idioma en el que hago esto realmente no importa. ¡Gracias!
Respuestas:
Empiece por comparar la distancia entre latitudes. Cada grado de latitud se encuentra a aproximadamente 111 kilómetros (69 millas) de distancia. El rango varía (debido a la forma ligeramente elipsoide de la Tierra) de 68.703 millas (110.567 km) en el ecuador a 69.407 (111.699 km) en los polos. La distancia entre dos ubicaciones será igual o mayor que la distancia entre sus latitudes.
Tenga en cuenta que esto no es cierto para las longitudes: la longitud de cada grado de longitud depende de la latitud. Sin embargo, si sus datos están limitados a un área (un solo país, por ejemplo), también puede calcular los límites mínimo y máximo para las longitudes.
Continuará con un cálculo de distancia rápido y de baja precisión que asume tierra esférica:
La distancia d del gran círculo entre dos puntos con coordenadas {lat1, lon1} y {lat2, lon2} viene dada por:
Una fórmula matemáticamente equivalente, que está menos sujeta a errores de redondeo para distancias cortas es:
d es la distancia en radianes
(6371 km es el radio promedio de la tierra )
Los requisitos computacionales de este método son mínimos. Sin embargo, el resultado es muy preciso para distancias pequeñas.
Luego, si está a una distancia determinada, más o menos, utilice un método más preciso.
GeographicLib es la implementación más precisa que conozco, aunque también se puede usar la fórmula inversa de Vincenty .
Si está utilizando un RDBMS, configure la latitud como clave principal y la longitud como clave secundaria. Consulte por un rango de latitud, o por un rango de latitud / longitud, como se describe anteriormente, luego calcule las distancias exactas para el conjunto de resultados.
Tenga en cuenta que las versiones modernas de los principales RDBMS admiten consultas y tipos de datos geográficos de forma nativa.
fuente
Según la latitud, la longitud y la distancia del usuario actual que desea encontrar, la consulta sql se muestra a continuación.
@latitude y @longitude son la latitud y la longitud del punto. La latitud y la longitud son las columnas de la tabla de distancias. El valor de pi es 22/7
fuente
Las extensiones de PostgreSQL GIS pueden ser útiles, ya que es posible que ya implemente gran parte de la funcionalidad que está pensando implementar.
fuente
Tank´s Yogihosting
Tengo en mi base de datos un grupo de tablas de Open Streep Maps y probé con éxito.
La distancia funciona bien en metros.
fuente
Estas preguntas pueden resultarle útiles:
fuente
Como mencionó biziclop, una especie de árbol de espacio métrico probablemente sería su mejor opción. Tengo experiencia en el uso de árboles kd y árboles cuádruples para hacer este tipo de consultas de rango y son increíblemente rápidos; tampoco son tan difíciles de escribir. Sugeriría buscar en una de estas estructuras, ya que también le permiten responder otras preguntas interesantes como "¿cuál es el punto más cercano en mi conjunto de datos a este otro punto?"
fuente
Lo que necesitas es una búsqueda espacial. Puede utilizar la búsqueda espacial de Solr . También tiene el tipo de datos lat / long incorporado, verifique aquí .
fuente
Puede convertir la latitud-longitud al formato UTM, que es un formato métrico que puede ayudarlo a calcular distancias. Entonces puede decidir fácilmente si el punto cae en una ubicación específica.
fuente
Dado que dice que cualquier idioma es aceptable, la elección natural es PostGIS:
SELECT * FROM places WHERE ST_DistanceSpheroid(geom, $location, $spheroid) < $max_metres;
Si desea utilizar el dato WGS, debe configurarlo
$spheroid
en'SPHEROID["WGS 84",6378137,298.257223563]'
Suponiendo que haya indexado
places
por lageom
columna, esto debería ser razonablemente eficiente.fuente
Gracias a la solución proporcionada por @yogihosting, pude lograr un resultado similar de columnas sin esquema de mysql con los códigos que se muestran a continuación:
Tenga en cuenta que el fragmento de código anterior utiliza la conexión de doctrine DB y PHP
fuente
puedes comprobar esta ecuación, creo que te ayudará
fuente