geomfromtext - mysql point latitude longitude
Almacenamiento de valores Lat Lng en MySQL utilizando el tipo de punto espacial (4)
Tecnología utilizada: MySQL 5.1 y PHP 5.3
Solo estoy diseñando una nueva base de datos para un sitio que estoy escribiendo. Estoy buscando la mejor manera de almacenar ahora los valores Lat y Lng.
En el pasado he estado usando DECIMAL y usando una selección de PHP / MySQL en el formulario:
SQRT(POW(69.1 * (fld_lat - ( $lat )), 2) + POW(69.1 * (($lon) - fld_lon) * COS(fld_lat / 57.3 ), 2 )) AS distance
para encontrar los lugares de correspondencia más cercanos.
Comenzando a leer más sobre las nuevas tecnologías, me pregunto si debería usar Spatial Extensions. http://dev.mysql.com/doc/refman/5.1/en/geometry-property-functions.html
Sin embargo, la información es bastante delgada en el terreno y tenía una pregunta sobre cómo almacenar los datos. En lugar de usar DECIMAL, ¿usaría ahora POINT como un tipo de datos?
Además, una vez almacenado como un PUNTO, ¿es fácil obtener los valores Lat Lng de él en caso de que quiera trazarlo en un mapa o también debo almacenar los latitudes como DECIMALES nuevamente?
Sé que debería usar PostGIS ya que la mayoría de las publicaciones aquí dicen que ¡simplemente no quiero aprender una nueva DB!
Seguir
He estado jugando con el nuevo tipo de PUNTO. He podido agregar valores Lat Lng usando lo siguiente:
INSERT INTO spatialTable (placeName, geoPoint) VALUES( "London School of Economics", GeomFromText( ''POINT(51.514 -0.1167)'' ));
Luego puedo recuperar los valores Lat y Lng del Db usando:
SELECT X(geoPoint), Y(geoPoint) FROM spatialTable;
Todo esto se ve bien, sin embargo, el cálculo de distancia es el bit que necesito resolver. Aparentemente, MySQL tiene un marcador de posición para una función de distancia, pero no se lanzará por un tiempo. En algunas publicaciones, he descubierto que necesito hacer algo como lo siguiente, sin embargo, creo que mi código es ligeramente incorrecto:
SELECT
placeName,
ROUND(GLength(
LineStringFromWKB(
LineString(
geoPoint,
GeomFromText(''POINT(52.5177, -0.0968)'')
)
)
))
AS distance
FROM spatialTable
ORDER BY distance ASC;
En este ejemplo, geoPoint es un PUNTO ingresado en el DB usando el INSERT arriba.
GeomFromText(''POINT(52.5177, -0.0968)''
es un valor Lat Lng del que quiero calcular una distancia.
Más seguimiento
Más bien estúpidamente, acabo de poner en la parte REDONDA del SQL sin pensar realmente. Sacar esto me da:
SELECT
placeName,
(GLength(
LineStringFromWKB(
LineString(
geoPoint,
GeomFromText(''POINT(51.5177 -0.0968)'')
)
)
))
AS distance
FROM spatialTable
ORDER BY distance ASC
Lo cual parece darme las distancias correctas que necesito.
Supongo que lo único que necesita responder en este momento es si estoy pensando en hacerme la vida más difícil si utilizo Spatial ahora o si me estoy preparando para el futuro ...
Creo que siempre debes usar la abstracción de más alto nivel fácilmente disponible. Si sus datos son geoespaciales, entonces use objetos geoespaciales.
Pero ten cuidado. Mysql es la peor base de datos geoespaciales que existe. Está bien para los puntos, pero todas sus funciones poligonales están completamente rotas: cambian el polígono a su rectángulo delimitador y luego responden sobre eso.
El peor ejemplo que me ha afectado es que si tienes un polígono que representa a Japón y preguntas qué lugares hay en Japón, ¡Vladivostok entra en la lista!
Oracle y PostGIS no tienen este problema. Espero que MSSQL no lo haga y cualquier base de datos Java que use JTS ya que su motor no lo hace. Bueno geoespacial MySQL Geospatial Bad.
Acabo de leer aquí ¿Cómo se utilizan las consultas espaciales MySQL para encontrar todos los registros en radio X? que está fijado en 5.6.1.
Hoorah!
Es algo bueno, porque luego puedes usar índices espaciales en tus consultas. Limite a un cuadro delimitador, por ejemplo, para limitar cuántas filas comparar.
Mysql GIS yagni:
Si no tiene experiencia con SIG, aprender extensiones espaciales es prácticamente como aprender una nueva base de datos, además de un poco de matemática y muchos acrónimos. Mapas, proyecciones, srids, formatos ... ¿Tiene que aprender todo eso para calcular las distancias entre los puntos dados un cierto lat / long: probablemente no, va a integrar datos GIS de terceros o trabajar con algo más complejo que los puntos, qué sistema de coordenadas que vas a usar?
Volviendo a yagni: haga las cosas de la manera más simple posible, en este caso implemente su código en php o con SQL simple. Una vez que llegue a una barrera y decida que necesita espacio, lea en el sistema SIG, coordine sistemas, proyectos y convenciones.
Para entonces, es probable que desee PostGIS.
Si puede poner un código adicional en su back-end, use Geohash.
Codifica una coordenada en una cadena de una manera que los prefijos denotan un área más amplia. Cuanto más larga sea la cadena, más precisión tendrá.
Y tiene enlaces para muchos idiomas.
http://en.wikipedia.org/wiki/Geohash https://www.elastic.co/guide/en/elasticsearch/guide/current/geohashes.html