with locator google mysql database-design maps mapping latitude-longitude

locator - ¿Cuál es el tipo de datos ideal para usar cuando se almacena latitud/longitudes en una base de datos MySQL?



google maps php mysql demo (19)

Teniendo en cuenta que realizaré cálculos en pares lat / largos, ¿qué tipo de datos es el más adecuado para usar con una base de datos MySQL?


Almacenamos latitud / longitud X 1,000,000 en nuestra base de datos de Oracle como NÚMEROS para evitar errores de redondeo con dobles.

Teniendo en cuenta que la latitud / longitud al sexto decimal era una precisión de 10 cm, era todo lo que necesitábamos. Muchas otras bases de datos también almacenan lat / long al sexto lugar decimal.


Básicamente, depende de la precisión que necesite para sus ubicaciones. Usando DOBLE tendrás una precisión de 3.5nm. DECIMAL (8,6) / (9,6) baja a 16cm. FLOTADOR es de 1,7 m ...

Esta tabla muy interesante tiene una lista más completa: http://mysql.rjweb.org/doc.php/latlng :

Datatype Bytes Resolution Deg*100 (SMALLINT) 4 1570 m 1.0 mi Cities DECIMAL(4,2)/(5,2) 5 1570 m 1.0 mi Cities SMALLINT scaled 4 682 m 0.4 mi Cities Deg*10000 (MEDIUMINT) 6 16 m 52 ft Houses/Businesses DECIMAL(6,4)/(7,4) 7 16 m 52 ft Houses/Businesses MEDIUMINT scaled 6 2.7 m 8.8 ft FLOAT 8 1.7 m 5.6 ft DECIMAL(8,6)/(9,6) 9 16cm 1/2 ft Friends in a mall Deg*10000000 (INT) 8 16mm 5/8 in Marbles DOUBLE 16 3.5nm ... Fleas on a dog

Espero que esto ayude.



Cuando hice esto para una base de datos de navegación construida a partir de ARINC424 hice una buena cantidad de pruebas y mirando el código, usé un DECIMAL (18,12) (en realidad un NUMERIC (18,12) porque era firebird).

Los flotantes y los dobles no son tan precisos y pueden dar como resultado errores de redondeo que pueden ser algo muy malo. No puedo recordar si encontré datos reales que tuvieron problemas, pero estoy bastante seguro de que la incapacidad de almacenar con precisión en un flotador o un doble podría causar problemas

El punto es que al usar grados o radianes, conocemos el rango de los valores, y la parte fraccionaria necesita la mayoría de los dígitos.

Las extensiones espaciales de MySQL son una buena alternativa porque siguen el modelo de geometría de OpenGIS . No los usé porque necesitaba mantener mi base de datos portátil.


Depende de la precisión que requieras.

Datatype Bytes resolution ------------------ ----- -------------------------------- Deg*100 (SMALLINT) 4 1570 m 1.0 mi Cities DECIMAL(4,2)/(5,2) 5 1570 m 1.0 mi Cities SMALLINT scaled 4 682 m 0.4 mi Cities Deg*10000 (MEDIUMINT) 6 16 m 52 ft Houses/Businesses DECIMAL(6,4)/(7,4) 7 16 m 52 ft Houses/Businesses MEDIUMINT scaled 6 2.7 m 8.8 ft FLOAT 8 1.7 m 5.6 ft DECIMAL(8,6)/(9,6) 9 16cm 1/2 ft Friends in a mall Deg*10000000 (INT) 8 16mm 5/8 in Marbles DOUBLE 16 3.5nm ... Fleas on a dog

De: http://mysql.rjweb.org/doc.php/latlng

Resumir:

  • La opción disponible más precisa es DOUBLE .
  • El tipo de vista más utilizado es DECIMAL(8,6)/(9,6) .

A partir de MySQL 5.7 , considere usar tipos de datos espaciales (SDT), específicamente POINT para almacenar una sola coordenada. Antes de 5.7, SDT no admite índices (con la excepción de 5.6 cuando el tipo de tabla es MyISAM).

Nota:

  • Cuando se utiliza la clase POINT , el orden de los argumentos para almacenar las coordenadas debe ser POINT(latitude, longitude) .
  • Hay una sintaxis especial para crear un índice espacial .
  • El mayor beneficio de usar SDT es que tiene acceso a las funciones de análisis espacial , por ejemplo, calcular la distancia entre dos puntos ( ST_Distance ) y determinar si un punto está contenido dentro de otra área ( ST_Contains ).

Dependiendo de su aplicación, sugiero usar FLOAT (9,6)

Las claves espaciales le darán más características, pero en los puntos de referencia de producción, los flotadores son mucho más rápidos que las claves espaciales. (0,01 VS 0,001 en AVG)


En una perspectiva completamente diferente y más simple:

  • Si confía en Google para mostrar sus mapas, marcadores, polígonos, lo que sea, ¡deje que Google realice los cálculos!
  • ahorra recursos en su servidor y simplemente almacena la latitud y la longitud como una sola cadena ( VARCHAR ), por ejemplo: " -0000.0000001,-0000.000000000000001 " (longitud de 35 y si un número tiene más de 7 dígitos decimales, se redondea) ;
  • Si Google devuelve más de 7 dígitos decimales por número, puede obtener esos datos almacenados en su cadena de todos modos, en caso de que desee detectar algunas fugas o microbios en el futuro ;
  • puede usar su matriz de distancia o su biblioteca de geometría para calcular distancias o detectar puntos en ciertas áreas con llamadas tan simples como esta: google.maps.geometry.poly.containsLocation(latLng, bermudaTrianglePolygon))
  • hay un montón de API de "servidor" que puedes usar (en Python , Ruby on Rails , PHP , CodeIgniter , Laravel , Yii , Zend Framework , etc.) que utilizan la API de Google Maps.

De esta manera, no necesita preocuparse por la indexación de números y todos los demás problemas asociados con los tipos de datos que pueden arruinar sus coordenadas.


Estoy muy sorprendido por algunas respuestas / comentarios.

¿Por qué demonios alguien estaría dispuesto a "disminuir" previamente la precisión voluntariamente, y luego realizar cálculos en los peores números? Suena en última instancia estúpido.

Si la fuente tiene una precisión de 64 bits, ciertamente sería tonto arreglar voluntariamente la escala, por ejemplo. 6 decimales, y limita la precisión a un máximo de 9 excavaciones significativas (lo que sucede con el formato decimal 9.6 comúnmente propuesto).

Naturalmente, uno almacena los datos con la precisión que tiene el material de origen. La única razón para disminuir la precisión sería el espacio de almacenamiento limitado.

  • Almacene las figuras de origen con precisión original
  • Almacene las cifras calculadas desde la fuente en la precisión con la que se realiza el cálculo (por ejemplo, si el código de la aplicación utiliza dobles, almacene los resultados como dobles)

El formato decimal 9.6 provoca un fenómeno de snap-to-grid. Ese debería ser el último paso, si es que tiene que suceder.

No invitaría errores acumulados a mi nido.



Las Extensiones espaciales de MySQL son la mejor opción porque tiene la lista completa de operadores e índices espaciales a su disposición. Un índice espacial le permitirá realizar cálculos basados ​​en la distancia muy rápidamente. Tenga en cuenta que a partir de la versión 6.0, la extensión espacial aún está incompleta. No voy a dejar de lado MySQL Spatial, solo te hago saber las trampas antes de que llegues demasiado lejos en esto.

Si está tratando estrictamente con puntos y solo la función DISTANCIA, esto está bien. Si necesita realizar cálculos con polígonos, líneas o puntos de búfer, los operadores espaciales no proporcionan resultados exactos a menos que use el operador "relacionar". Vea la advertencia en la parte superior de 21.5.6 . Las relaciones tales como contiene, dentro o intersecciones están usando el MBR, no la forma geométrica exacta (es decir, una Elipse se trata como un Rectángulo).

Además, las distancias en MySQL Spatial están en las mismas unidades que su primera geometría. Esto significa que si está utilizando grados decimales, entonces sus medidas de distancia están en grados decimales. Esto hará que sea muy difícil obtener resultados exactos al obtener furthur del ecuador.


Las funciones espaciales en PostGIS son mucho más funcionales (es decir, no están limitadas a las operaciones de BBOX) que las funciones espaciales de MySQL. Échale un vistazo: enlace de texto


Los cálculos de Lat Long requieren precisión, así que use algún tipo de tipo decimal y haga que la precisión sea al menos 2 más alta que la cantidad que almacenará para realizar cálculos matemáticos. No sé acerca de los tipos de datos de mi sql, pero en el servidor SQL la gente a menudo usa float o real en lugar de decimal y se mete en problemas porque estos son números estimados y no reales. Así que solo asegúrate de que el tipo de datos que usas sea un tipo decimal verdadero y no un tipo decimal flotante y estarás bien.


MySQL usa el doble para todos los flotadores ... Entonces use el tipo doble. El uso de float conducirá a valores redondeados impredecibles en la mayoría de las situaciones


No hay necesidad de ir muy lejos, según Google Maps, lo mejor es FLOAT (10,6) para lat y lng.


Si bien no es óptimo para todas las operaciones, si está haciendo mosaicos de mapas o trabajando con un gran número de marcadores (puntos) con una sola proyección (por ejemplo, Mercator, como Google Maps y muchos otros marcos de mapas de mapas deslizantes esperan), he encontrado lo que Llamo a "Vast Coordinate System" para ser realmente, muy útil. Básicamente, usted almacena las coordenadas de píxeles xey en algún modo de acercamiento ampliado - yo uso el nivel de zoom 23. Esto tiene varias ventajas:

  • Realiza la costosa transformación de píxeles lat / lng a mercator una vez en lugar de cada vez que maneja el punto.
  • Obtener la coordenada de mosaico de un registro dado un nivel de zoom tiene un desplazamiento hacia la derecha.
  • Obtener la coordenada de píxeles de un registro requiere un desplazamiento a la derecha y otro AND a nivel de bits.
  • Los cambios son tan ligeros que es práctico hacerlos en SQL, lo que significa que puede hacer un DISTINTO para devolver solo un registro por ubicación de píxel, lo que reducirá el número de registros devueltos por el servidor, lo que significa menos procesamiento en la Interfaz.

Hablé de todo esto en una publicación reciente del blog: http://blog.webfoot.com/2013/03/12/optimizing-map-tile-generation/


Un FLOAT debería darle toda la precisión que necesita, y ser mejor para las funciones de comparación que almacenar cada coordenada como una cadena o similar.

Si su versión de MySQL es anterior a la 5.0.3, es posible que deba tener en cuenta ciertos errores de comparación de punto flotante .

Antes de MySQL 5.0.3, las columnas DECIMAL almacenan los valores con precisión exacta porque se representan como cadenas, pero los cálculos en los valores DECIMAL se realizan mediante operaciones de punto flotante. A partir de la versión 5.0.3, MySQL realiza operaciones DECIMAL con una precisión de 64 dígitos decimales, que deberían resolver los problemas de imprecisión más comunes cuando se trata de columnas DECIMAL



Use DECIMAL(8,6) para la latitud (90 a -90 grados) y DECIMAL(9,6) para la longitud (180 a -180 grados). 6 decimales están bien para la mayoría de las aplicaciones. Ambos deben estar "firmados" para permitir valores negativos.


TL; DR

Use FLOAT (8,5) si no está trabajando en la NASA / militar y no está haciendo sistemas de navegación de aviones.

Para responder completamente a tu pregunta, deberías considerar varias cosas:

Formato

  • grados minutos segundos : 40 ° 26 ′ 46 ″ N 79 ° 58 ′ 56 ″ W
  • grados decimales minutos : 40 ° 26.767 ′ N 79 ° 58.933 ′ W
  • grados decimales 1 : 40.446 ° N 79.982 ° W
  • grados decimales 2 : -32.60875, 21.27812
  • ¿Algún otro formato hecho en casa? Nadie le prohíbe crear su propio sistema de coordenadas centrado en el hogar y almacenarlo como rumbo y distancia desde su hogar. Esto podría tener sentido para algunos problemas específicos en los que estás trabajando.

Entonces, la primera parte de la respuesta sería: puede almacenar las coordenadas en el formato que usa su aplicación para evitar conversiones constantes de un lado a otro y hacer consultas SQL más simples.

Lo más probable es que use Google Maps u OSM para mostrar sus datos, y GMaps está usando el formato de "grados decimales 2". Así será más fácil almacenar las coordenadas en el mismo formato.

Precisión

Entonces, le gustaría definir la precisión que necesita. Por supuesto, puede almacenar coordenadas como "-32.608697550570334,21.278081997935146", pero ¿alguna vez se preocupó por los milímetros mientras navegaba al punto? Si no estás trabajando en la NASA y no estás haciendo satélites, cohetes o trayectorias de aviones, deberías estar bien con varios metros de precisión.

El formato comúnmente utilizado es de 5 dígitos después de los puntos, lo que le da una precisión de 50 cm.

Ejemplo : hay 1 cm de distancia entre X, 21.278081 8 y X, 21.278081 9 . Por lo tanto, 7 dígitos después del punto le dan una precisión de 1/2 cm y 5 dígitos después del punto le dará una precisión de 1/2 metro (porque la distancia mínima entre puntos distintos es de 1 m, por lo que el error de redondeo no puede ser más de la mitad). Para la mayoría de los propósitos civiles debería ser suficiente.

El formato de minutos decimales (40 ° 26.767 ′ N 79 ° 58.933 ′ W) le da exactamente la misma precisión que 5 dígitos después del punto

Almacenamiento de espacio eficiente

Si ha seleccionado el formato decimal, entonces su coordenada es un par (-32.60875, 21.27812). Obviamente, 2 x (1 bit para signo, 2 dígitos para grados y 5 dígitos para exponente) serán suficientes.

Así que aquí me gustaría apoyar a Alix Axel en los comentarios que dicen que la sugerencia de Google para almacenarlo en FLOAT (10,6) es realmente extra, porque no necesita 4 dígitos para la parte principal (ya que el signo está separado y la latitud es limitada a 90 y la longitud se limita a 180). Puede usar fácilmente FLOAT (8,5) para una precisión de 1 / 2m o FLOAT (9,6) para una precisión de 50 / 2cm. O incluso puede almacenar lat y long en tipos separados, porque FLOAT (7,5) es suficiente para lat. Ver reference tipos de flotador de MySQL. Cualquiera de ellos será como FLOAT normal e igual a 4 bytes de todos modos.

Por lo general, el espacio no es un problema en la actualidad, pero si realmente desea optimizar el almacenamiento por algún motivo (Descargo de responsabilidad: no realice la optimización previa), puede comprimir lat (no más de 91 000 valores + signo) + largo (no más de 181 000 valores + signo) a 21 bits, lo que es significativamente menor que 2xFLOAT (8 bytes == 64 bits)