Tengo una tabla de códigos postales que incluye el lat central, lng para cada código postal. Lo uso para obtener una lista de códigos postales dentro de un radio de milla dado desde cualquier punto arbitrario.
Se me ocurrió que, solo porque el punto central de un zip no esté dentro de un radio dado, no significa que el zip no esté dentro del radio.
Utilicé mis habilidades artísticas súper avanzadas para ilustrar el punto aquí:
Las manchas de rayas verdes representan los códigos postales A, B y C.
Las manchas rojas son los centros geográficos de cada código postal.
El punto fucsia es la ubicación de destino, y ..
El círculo azul abultado está a un radio de 1 milla de la ubicación del objetivo
Si ejecuto una consulta para todos los códigos postales dentro de un radio de 1 milla de la mancha rosa, solo se devolverán los códigos postales B y C ya que el punto central para el zip A no está dentro del radio de una milla, aunque la mancha rosa en sí está claramente en el código postal A.
SELECT *,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.y))
* COS(RADIANS(p.longpoint) - RADIANS(z.x))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.y)))) AS dist
FROM standard_zip AS z
JOIN ( /* these are the query parameters */
SELECT $lat AS latpoint, $lng AS longpoint,
$miles AS radius, 69 AS distance_unit
) AS p ON 1=1
WHERE z.y
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.x
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
ORDER BY dist
¿Cómo diablos escribo una consulta que incluirá zip A en los resultados?
Tengo acceso a espacial / geometría para cada código postal que puedo agregar a la tabla si es necesario, pero no tengo idea de cómo lo usaría para este propósito en MySQL.
Editar : Pasé un día leyendo los documentos de Oracle y MySQL para datos espaciales y logré convertir mis datos espaciales a MySQL con éxito . ¿Cómo hago para escribir una consulta similar que use la columna de geometría en lugar de la longitud y la longitud? Estoy usando datos 2D ... la geometría son solo polígonos y multipolígonos ...
Creo que lo descubrí ...
select
*
from
(
select
MIN(st_distance(geom, POINT(-82.765136, 28.0914015))) * 69 as miles,
zip
from
zip_spatial
group by
zip
order by
miles asc
) d
where
d.miles < 5
Dejaré la recompensa abierta por ahora en caso de que alguien tenga una solución mejor y más eficiente.
Cualquier intento de incluir A probablemente incluirá D, E, F, G. El problema no puede resolverse sin tener una ruta exacta que defina cada área de código postal.
Encuentre dicha base de datos, luego construya un
SPATIAL
índice usando tales polígonos arbitrarios.fuente
Lo estás haciendo mal. Primero, si es posible, use PostGIS, que es el RDMBS líder con solución espacial.
Entonces quieres seguir estos pasos.
shp2pgsql
Indice la geometría que importó.
Ejecute una consulta de Punto de interés (POI) contra los archivos de forma. El punto de interés en su caso son los cables de entrada, esto se verá así,
ℹ 1609.344 Metros = 1 Milla
MySQL
Con MySQL tendrás
Se usa
MBRIntersects
para utilizar el índice espacial. La consulta final debe verse comofuente
ST_DWithin
porMBRIntersects
Consulte este conjunto de datos de GreatData.com (tenga en cuenta que esto no es de código abierto sino un servicio pago).
Utilizan la densidad de población en lugar del centro de la cremallera.
Y cómo usar el tipo de datos espaciales del servidor sql para obtener resultados correctos y rápidos.
Espero que esto ayude.
fuente