Cargar fichero GPX (XML) y acceder a los datos
Desde hace un tiempo estoy trabajando con ficheros de rutas o «Tracks» que provienen de dispositivos GPS (Global Positioning System). Un track o una ruta, no es más que una sucesión de coordenadas de Latitud y Longitud. Adicionalmente esos puntos pueden contener más información como Elevación, Fecha y hora,…
Existen infinidad de formatos para almacenar «Tracks» muchos de ellos provenientes de marcas concretas de receptores GPS (Garmin, DeLorme, Holux, Magellan, Tomtom…) y otros provenientes de programas de software conocidos como OziExplorer, CompeGPS o los relacionados con Google Maps.
Además existe también un formato genérico y bastante aceptado como estandard, que almacena puntos con estructura XML. Es el formato GPX (GPS eXchange Format).
La idea de esta entrada es generar código para trabajar desde delphi con un track en formato genérico GPX. Poder abrirlo y cargar los valores sin problemas y posteriormente exportarlo a KML. Aunque una vez recuperados los datos desde Delphi, la exportación a otros formatos será muy similar.
Leer un archivo GPX
Lo primero que vamos a hacer para poder leer un archivo de tipo GPX es generar una pieza intermedia que nos permita fácilmente trasladar los datos desde un XML (con una estructura determinada) a un Dataset (en nuestro caso un TClientDataset).
NOTA: Para utilizar como ejempos, en la web podéis encontrar infinidad de archivos de este tipo; Yo para las pruebas utilizaré un par de archivos de rutas distintos que podeís descargar aquí.
Para ello utilizaremos la herramienta XML Mapper de Delphi, accesible desde el menú de Tools (o también desde el Menu de programa, en el mismo grupo donde está instalado Delphi).
PASO1: Abrir fichero GPX; Aunque la extensión no es XML, sí lo es la estructura del fichero, así que la herramienta reconocerá los campos y en la parte izquierda del programa podremos ver la estructura del fichero con los diferentes campos disponibles. En este caso vemos que el fichero contiene una serie de campos correspondientes al track, como creator, versión,… y luego un «Nested Dataset»; Un Dataset «anidado», que contiene todos los puntos del track con los campos Lat (latitud), Lon (longitud), Ele (altura o elevación) y time (fecha/hora).
PASO2: Generar un Datapacket; Una vez que la estructura se ha leído correctamente podemos generar lo que XML Mapper llama un DataPacket; Que viene a ser algo así como los datos que tenemos en el XML, pero en formato de Dataset y además nos permitirá guardar el archivo de transformación (que es realmente lo importante).
Este archivo de transformación nos permitirá posteriormente leer cualquier fichero XML con la misma estructura que este y realizar la traducción a «formato dataset» de forma automática.
Para ello Desde el menú contextual seleccionamos todos los campos (Select All) y en el menú de Create escogemos Datapacket from XML (Ctrl+D). Con ello habremos generado nuestro fichero de transformación y el Dataset final.
En la parte derecha de la pantalla podemos ver la misma estructura que teníamos en el XML pero en «formato datapacket». Podemos comprobar cómo se ha realizado la transformación y que los datos se leen correctamente utilizando un botón que hay en la parte inferior de la pantalla llamado «Create and Test Transformation«.
Esto nos abre un Grid y nos muestra los datos provenientes del Dataset que se ha generado utilizando el fichero de transformación. Esto es lo que posteriormente nosotros queremos repetir en nuestro programa. Además como la estructura XML posee un «DataSet anidado», si pulsamos doble click sobre el campo trkpt, se abre un segundo Dataset que contiene todos los registros de los puntos que hay en la ruta.
En este ejemplo hemos realizado una traducción directa, pero el programa (antes de generar la transformación) nos permite modificar los campos que queremos «mapear» entre el origen (el XML) y el destino (Datapacket/Dataset), de forma que podemos aplicar determinados cambios, variaciones o filtros a los datos de entrada.
PASO3: Guardar el fichero de transformación; Una vez realizado esto sólo nos queda (lo más importante) guardar el fichero de transformación, que nos asegura que a partir de este momento podremos repetir esta misma transformación (con cualquier otro fichero de entrada que sea del mismo formato que este). Desde el Menú de File seleccionamos Save Transformation. Asignaremos anuestro fichero el nombre de GPX_To_DP.xtr (GPX to DataPacket).
Utilizar un fichero de transformación
Una vez que hemos generado nuestro fichero de tranformación GPX_To_DP.xtr, vamos a ver cómo nos puede ser útil en un programa delphi para tratar ficheros de rutas guardaos en formato GPX. Para ello utilizaremos 2 TClientDataset, no para la ruta y otro para los puntos de la ruta (a modo de Master-Detail).
Creamos un un nuevo proyecto y un formulario con los siguientes componentes:
- Un DBGrid, un TDatasource y un TClientDataset para los puntos
- Un DBGrid, un TDatasource, un TClientDataset y un TXMLTransformProvider para los datos del track.
Cada uno de los DBGrid va ligado al TDataset y cada uno de estos al TClientDataset.
En el XMLTransformProvider deberemos colorcar en la propiedad TransformRead, el fichero de transformación que hemos generador mediante la herramienta XML Mapper.
Como hemos visto, el campo trkpt del TClientDataset asociado al track es un campo de tipo TDataset (en concreto un TDatasetField). Para mostrarlo utilizaremos el segundo TClientDataset que hemos colocado en el formulario (cdsPoints).
En la propiedad DatasetField del TClientDataset cdsPoints asignamos el campos del primer Dataset (en este caso trkpt). Con esto visualizaremos en el segundo DBGrid los puntos que contiene el track.
Una vez hecho esto, bastará con las siguentes líneas de código para conseguir leer el contenido de cualquier fichero con formato GPX. Únicamente hay que asignar el fichero de transformación y el fichero fuente XML.
var b:Boolean; path:string; begin // Abrir el diálogo b := OpenDialog1.Execute; if (b) then begin // Asignar fichero de transformación path := ExtractFilePath(Application.ExeName) + 'GPX_To_DP.xtr'; XMLTransformProvider.TransformRead.TransformationFile := path; // Fichero XML (GPX) de ruta XMLTransformProvider.XMLDataFile := OpenDialog1.FileName; // Abrir el Dataset cdsTrack.Open; end; end; |
El resultado son los 2 DBGrid con los datos del Track:
Podéis descargar los ficheros de ejemplo de las rutas y el código fuente y binarios en los siguientes enlaces:
<Rutas de ejemplo>
<SOURCES DEL EJEMPLO>
<BINARIOS DEL EJEMPLO>
Una vez que tenemos los datos en formato accesible (fácil) para nosotros, lo siguiente que vamos a proponer es exportarlos a un formato KML (Google Maps) y visualizar la ruta/track sobre un Mapa de Google Maps.
Algo como lo que se ve a continuación, aunque eso lo dejo para la próxima entrada:
Un saludo.
Os adjunto algunas direcciones de interés…
_____________________________________________________________________
Referencias:
- Wiki GPX (GPS eXchange Format)
- Official GPX 1.1 Schema
- GPX 1.1 Schema Documentation
- Wikiloc; Página con track GPS
- cicloide; Página con track GPS
- Referencia del formato KML
- Esquema del formato KML
Embarcadero MVP.
Analista y Programador de Sistemas Informáticos.
Estudios de Informática (Ingeniería Técnica Superior) en la UPC (Universidad Politécnica de Barcelona).
Llevo utilizando Delphi desde su versión 3. Especialista en diseño de componentes, Bases de Datos, Frameworks de Persistencia, Integración Continua, Desarrollo móvil,…
Hola
Quisiera una libreria o cpmponente o codigo en delphi para pasar de una tabla en Delphi a un archivo en gpx
Gracias de antemano por la ayuda
Puedes realizar el paso contrario al que hemos descrito en este artículo. Se puede crear un archivo de transformación para generar el GPX a partir del DataPacket.
Un saludo.
Como no podia ser de otra manera muy bueno el articulo, estare a la espera de la siguiente entrada.
Saludos.
Estoy realizando un programa que maneja de gps para celulares y quisiera saber mas afondo que librerías puedo utilizar para el gps y después de tenerlos con que programa puedo visualizar los datos
@jaime andres arango
Hola Jaime.
En los ejemplos con Delphi que traen las nuevas versiones hay algunos referentes a Posicionamiento GPS y visualización en mapas de Google, utilizando el componente WebBroser.
Puedes echarles un vistazo a ver si se acercan a lo que necesitas.
Aquí (http://www.appmethod.com/codesnippets) también tienes una serie de ejemplos con código.
Hola , muchas gracias por enseñarnos!!!!!…
Mi consulta es al leer un archivo con Waypoit Garmin (en Gpx) no me despliega la información, ¿ se trata de otra manera este archivo?
Muchas Gracias de Antemano.
@MMurgas
¿Qué extensión tiene el fichero que estás intentando leer?
Si es GPX es posible que modificando un poco la parte que lee el fichero puedas adquirir esos datos sin muchos problemas.
Fíjate en la parte que carga el XML.
@Germán Estévez
Muchas Gracias Neftali efectivamente habia que revisar el XML pero funciona perfecto….me sirvio
mucho ….
Excelente su Web …un saludo
Aunque el post es un poco antiguo, espero que el hilo siga activo.
No he trabajado con Delphi, pero me interesa ese manejo de archivos GPX. He instalado Delphi «7 second edition» y no encuentro el XML Mapper.
¿Es demasiado antigua la versión?.
Gracias por el tutorial, claro y conciso, y un saludo.
@Jose
Desconozco qué versión es la «Second Edition» de la que hablas, pero no me suena que sea una versión «oficial».
Delphi 7 trae el XMLMapper en el menú de tools.
Tal vez la versión que has instalado no tenga el package correspondiente o lo tenga desinstalado.
@Germán Estévez
Gracias, Neftalí.
Estoy un poco perdido. He programado bastante en Visual Basic pero veo que me falta entender la estructura de Delphi. He visto lo que propones en este post y me he lanzado a intentarlo. Uso bastante el GPS y tu idea me parece muy buena.
Tendré que empezar por lo básico :-(
Saludos.
@Jose
Hola Jose.
Digamos que no has empezado con el post más sencillo. ;-)
Aquí a parte de la programación púramente de delphi está el tema del XML Mapper que añade un segundo nivel de complejidad.
Tal vez deberías empezar con otro ejemplo, que no utilice el XML mapper. De esta forma puedes centrarte en el código delphi y dejar para más tarde esa parte.
El XML Mapper es una forma de cargar un XML, pero hay muchas otras. Puedes utilizar componentes de terceros, librerías o hacerlo «a mano». La segunda parte es qué hacer con esos datos una vez están cargados, pero debería ser independiente de cómo los cargues.
Empieza si quieres con este otro ejemplo (http://neftali.clubdelphi.com/?p=1361). También hace la carga de un XML (un KML en realidad es también un fichero XML con estructura similar), pero en este caso la hace «a mano» de forma más sencilla (lee directamente el fichero).
Un saludo.