GEOHASH MySQL – Agrupando coordenadas GPS cercanas

Desde el post anterior, estoy queriendo hacer otro mostrando como se puede usar el ffmpeg, pero estoy armando unos timelapses buenos primero, para mostrar el verdadero potencial, aparte estoy investigando más sobre los parámetros que se pueden usar, para mejorar la performance, y tratando de entenderlos mejor, en cuanto tenga eso solucionado, les mostraré.

muchos puntos en un solo lugarAhora quiero hablarles de otro proyecto en el que estoy (sí, sé que es malo tener varios proyectos en simultáneo, porque no termino ni lo uno ni lo otro, ¿pero que puedo hacer?, mi mente se dispersa muy rápido), el proyecto con el que estoy, es relacionado a ir almacenando puntos GPS.

Ahora mismo estoy teniendo un problema ya que cuando se está mucho tiempo en un solo lugar, normalmente  como los aparatos GPS tienen cierto margen de error de unos metros, se empiezan a formar nubes de puntos en un solo lugar, haciendo que uno tenga cientos o inclusive miles de puntos si uno estuvo mucho tiempo quieto.

Buscando por la red, encontré que la forma en la que muchos solucionaron el problema, es usando algo que se conoce como geo-hashing, de que se trata? Bueno, la Wikipedia nos dice lo siguiente:

Geohash is a geocoding system invented by Gustavo Niemeyer and placed into the public domain. It is a hierarchical spatial data structure which subdivides space into buckets of grid shape, which is one of the many applications of what is known as a Z-order curve, and generally space-filling curves.

Geohashes offer properties like arbitrary precision and the possibility of gradually removing characters from the end of the code to reduce its size (and gradually lose precision).

As a consequence of the gradual precision degradation, nearby places will often (but not always) present similar prefixes. The longer a shared prefix is, the closer the two places are.

que mal y pronto se traduce en algo parecido a esto:

Geohash es un sistema de geocodificación inventado por Gustavo Niemeyer y que fue hecho de dominio público. Es una estructura jerárquica de datos espaciales que divide el espacio en retazos menores formando una grilla (tal vez se pueda traducir como red también), que es  una de las muchas aplicaciones de lo que se conoce como una curva de orden Z, y generalmente curvas de relleno de espacio.

Los geohashes ofrecen propiedades como precisión arbitraria y la posibilidad de gradualmente remover caracteres del final del código para reducir su tamaño (y gradualmente perder precisión).

Como consecuencia de la degradación de la precisión, lugares cercanos a menudo (pero no siempre) presentarán prefijos similares.

Esto básicamente, era lo que estaba buscando!!! 😀

En mi caso yo uso un hash de doce caracteres, por ej. tk2zym7mjztt 
Tengo entendido que a partir de ciertas versiones de MySQL y tambien en MariaDB estas funciones serán nativas, pero como no es mi caso, tuve que buscar alguien que las haya hecho, de no ser así terminaría viendo como funciona por dentro para hacer una yo mismo (por suerte no fue el caso). En el repositorio de nowelium encontré la solución aquí. Bastaba con implementar su código que quedará como procedimiento almacenado dentro de mi base de datos, para cuando lo necesite.

Ejemplo de una consulta SQL, que actualmente estoy usando para obtener los puntos.

SELECT p.*, CONVERT_TZ(fecha_sistema, "+00:00", "-04:00") as fecha_sistema_local,
       SUBSTRING(geohash_encode(latitud, longitud, 12), 1, 8) as gh
FROM `posiciones` `p`
WHERE CONVERT_TZ(fecha_sistema,"+00:00","-04:00") > '2016-05-17 00:00:00'
       AND CONVERT_TZ(fecha_sistema,"+00:00","-04:00") <= '2016-05-17 23:50:20'
AND `gps_disponible` = 'A'
GROUP BY `gh`
ORDER BY `fecha_sistema` DESC 

Menos puntos en el mismo lugarEn el substring que se hace sobre el resultado de la función, aumentando el numero, en este caso 8 en dirección al 12, se obtendrán más puntos, y disminuyendo, es decir, acercándolo a 1, se irán obteniendo menos puntos ( esto es, se perderá precisión). En mi caso, yo no quería perder tanta precisión, así que fui probando finalmente el 8 resulto ser el número que necesitaba. Esto redujo de cerca de 236 puntos que tenía inicialmente a unos 90 aproximadamente, donde igual tengo noción del recorrido hecho.

Bueno, eso es lo que tenía para escribir hoy, antes de ir a dormir.

Saludos!!!