Passer des données de Google Earth ou Google My Maps à OSMAnd

Ceci est une description d’un conversion conservant certaines styles comme les couleurs et les groupements lors du passage de KML vers GPX. Le problème: Google Maps et Google Earth n’exportent proprement que du KML et OSMAnd n’importe que du GPX. Sans prendre des précautions, symboles et couleurs sont perdus.

Le procédé décrit est très „artisanal“, mais il ne requiert pas de programmes payants. Beaucoup de passages peuvent être optimisés. Des conseils d’amélioration sont bien venus!

Préparation

  • N’utiliser que le nom d’objet de Marker et Path et pas les autres champs sous Google Earth. Sous Google Maps il est possible d’utiliser aussi le champ description.
  • Dans les noms d’objets de Marker et de Path ne pas utilser de _ car cela génère des sous-catégories sous OSMAnd.
  • Utiliser des préfixes et/ou suffixes pour différencier plus tard les couleurs et catégories sous OSMAnd. Par exemple dans le nom
    monu-aquedutoDaAguasLivres-marAdim10-1730-AA j’identifie monu et AA.

Conversion

Je n’ai pas de programme tout prêt, il s’agit d’un procédé un peu compliqué:

  • Enregistrer le groupe concerné sous KMZ car uniquement le KMZ garde toutes les infos graphiques. Tous les groupements seront perdus dans les fichiers GPX résultants, ceux-ci ne connaissant sous OSMAnd que des catégories (donc un seul niveau de différenciation).
  • Dézipper le KMZ et sauvegarder le doc.kml dedans.
  • Séparer ce fichiers en points.KML et paths.KML (mais garder les entêtes et fins de fichiers, donc des fichiers valides). Éliminer tout retour à la ligne dans une balise XML.
  • Convertir les deux en points.GPX et paths.GPX sous GPSBabel ou ailleurs. Éliminer tout double espace dans les fichiers résultants.

Traitement des points (Marker)

Pour faire ressortir les couleurs sous OSMAnd il faudrait un bon éditeur XML scriptable, mais ils sont tous payants. On peut cependant se servir de la console du navigateur (j’utilise Google Chrome). L’idée est de se servir des préfixes et suffixes pour attribuer des codes de couleur et de catégories pendant que l’on transforme le fichier GPX initial. Les points (<wpt>) y ressemblent à ceci:

<wpt lat="38.726536000" lon="-9.166323000">
  <ele>0.000000</ele>
  <name>monu-aquedutoDaAguasLivres-marAdim10-1730</name>
  <cmt>description: venir le matin&lt;br&gt;categorie: natu</cmt>
  <desc>description: venir le matin&lt;br&gt;categorie: natu</desc>
</wpt>

Nous avons besoin des parties vertes et de utilisons l’information en rouge pour attribuer une catégorie. À la fin il nous faut un tel <wpt>:

<wpt lat="38.726536000" lon="-9.166323000">
  <name>monu-aquedutoDaAguasLivres-marAdim10-1730</name>
  <desc>venir le matin</desc>
  <extensions><color>#b4F5A9A9</color></extensions>
  <type>monument</type>
</wpt>

Utiliser le navigateur et sa console

On prend un fichier HTML et on y introduit à la fin le fichier GPX sortant de GPSBabel tel quel. Le JavaScript traitera la partie GPX et la transformera. Cette transformation est visible sous la console (Ctrl+Alt+J).

Le fichier HTML à ouvrir localement dans le navigateur:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
   <script>
     function init(){
       var elems = document.getElementsByTagName("wpt");
       var trackDoubles = Array(); // OSMAnd NE SUPPORTE PAS LES IDS DOUBLES
       for (var i = 0;i < elems.length; i++){
         var nameHere = elems[i].getElementsByTagName("name")[0].innerHTML; // LISTE DES WAYPOINTS

         // EFFACER LES BALISES INUTILES
         if(elems[i].getElementsByTagName("extensions")[0]){
           elems[i].removeChild(elems[i].getElementsByTagName("extensions")[0]);
         }
         if(elems[i].getElementsByTagName("type")[0]){
           elems[i].removeChild(elems[i].getElementsByTagName("type")[0]);
         }
         if(elems[i].getElementsByTagName("ele")[0]){
           elems[i].removeChild(elems[i].getElementsByTagName("ele")[0]);
         }
         if(elems[i].getElementsByTagName("cmt")[0]){
           elems[i].removeChild(elems[i].getElementsByTagName("cmt")[0]);
         }
         // TRAITER LA DESCRIPTION SI DIPONIBLE
         if(elems[i].getElementsByTagName("desc")[0]){
           var myContent = elems[i].getElementsByTagName("desc")[0].textContent;
           if(myContent.match(/description: \<br/)){ // VIDE
             elems[i].removeChild(elems[i].getElementsByTagName("desc")[0]);
           } else { // AVEC DU CONTENU
             myContent = myContent.replace(/description: /i, "");
             myContent = myContent.split("<br");
             elems[i].getElementsByTagName("desc")[0].textContent = myContent[0];
          }
        }

        var items = Array(); // LISTE DE CATEGORIES/COULEURS
        // ROUGE
        items["monu"] = ["FF0000", "F5A9A9", "B40404", "rouge", "port-monument"];
        items["vill"] = ["FF0000", "F5A9A9", "B40404", "rouge", "port-ville"];
        items["muse"] = ["FF0000", "F5A9A9", "B40404", "rouge", "port-musee"];
        items["arch"] = ["FF0000", "F5A9A9", "B40404", "rouge", "port-archeologie"];
        items["phar"] = ["FF0000", "F5A9A9", "B40404", "rouge", "port-phare"];
        // ORANGE
        items["hike"] = ["FF8000", "F5D0A9", "DBA901", "orange", "port-rando"];
        // JAUNE
        items["shop"] = ["FFFF00", "ACFA58", "D7DF01", "jaune", "port-magasin"];
        items["rest"] = ["FFFF00", "ACFA58", "D7DF01", "jaune", "port-restaurant"];
        items["food"] = ["FFFF00", "ACFA58", "D7DF01", "jaune", "port-aliments"];
        items["marc"] = ["FFFF00", "ACFA58", "D7DF01", "jaune", "port-marche"];
        // VERT JAUNE
        items["natu"] = ["80FF00", "ACFA58", "5FB404", "vertJaune", "port-nature"];
        // VERT BLEU
        items["vues"] = ["00FF80", "81F7BE", "04B45F", "vertBleu", "port-panorama"];
        // TURQUOISE
        items["toil"] = ["00FFFF", "A9F5F2", "01DFD7", "turquoise", "port-toilettes"];
        items["eaup"] = ["00FFFF", "A9F5F2", "01DFD7", "turquoise", "port-eau-potable"];
        // TURQUOISE FONCE
        items["camp"] = ["00BFFF", "81DAF5", "0489B1", "turquoiseBleu", "port-camping"];
        items["empl"] = ["00BFFF", "81DAF5", "0489B1", "turquoiseBleu", "port-emplacement"];
        items["sost"] = ["00BFFF", "81DAF5", "0489B1", "turquoiseBleu", "port-aire-cc"];
        // BLEU
        items["park"] = ["0040FF", "A9BCF5", "0404B4", "bleu", "port-parking"];
        items["tran"] = ["0040FF", "A9BCF5", "0404B4", "bleu", "port-transport"];
        // VIOLET
        items["chap"] = ["BF00FF", "E2A9F3", "8904B1", "violet", "port-chapelle"];
        items["egli"] = ["BF00FF", "E2A9F3", "8904B1", "violet", "port-eglise"];
        // ROSE
        items["site"] = ["FF00FF", "F5A9F2", "B404AE", "rose", "port-site-point"];
        // GRIS
        items["info"] = ["848484", "E6E6E6", "585858", "gris", "port-information"];

        // TRANSFORMATION
        var typeHere = nameHere.split("-");
        var newElem = document.createElement("extensions"); 
        var newSubElem = document.createElement("color");
        var newSubElemCont;
        var cat = "";
        if(nameHere.match(/-OK$/)){
          newSubElemCont = document.createTextNode("#b4"+items[typeHere[0]][2]); // SUFFIXE SITE DÉJÀ VISITÉ
          cat = items[typeHere[0]][4] + "-D";
        } else if(nameHere.match(/-A+$/)){
          newSubElemCont = document.createTextNode("#b4"+items[typeHere[0]][0]); // SUFFIXE SITE IMPORTANT
          cat = items[typeHere[0]][4] + "-A";
        } else {
          newSubElemCont = document.createTextNode("#b4"+items[typeHere[0]][1]); // SITE NORMAL
          cat = items[typeHere[0]][4];
        }

        newSubElem.appendChild(newSubElemCont); // AJOUTER BALISE COULEUR
        newElem.appendChild(newSubElem);
        elems[i].appendChild(newElem);
        var newElem = document.createElement("type"); // AJOUTER BALISE CATEGORIE
        var newElemCont = document.createTextNode(cat);
        newElem.appendChild(newElemCont);
        elems[i].appendChild(newElem);

        // DOUBLES IDS
        if(nameHere in trackDoubles){
          trackDoubles[nameHere]++;
          nameHere += "-"+trackDoubles[nameHere];
          elems[i].getElementsByTagName("name")[0].innerHTML = nameHere;
        } else {
          trackDoubles.push(nameHere);
          trackDoubles[nameHere] = 1;
        }
      }
      alert(elems.length); // AFFICHE NOMBRE DE POINTS TRAITÉS
    }

    function printDOM() { // ECRIRE LE CONTENU CHANGÉ DANS LA CONSOLE
      console.log(document.getElementsByTagName('body')[0].innerHTML) ;
    }
  </script>
</head>
<body onload="init()">
  <h1 id="hhh">GPX</h1>
  <button onclick="printDOM()">Print DOM</button><hr/>

  <!-- ICI VIENT LE FICHIER points.GPX ENTIER -->

<?xml version="1.0" encoding="UTF-8"?>
  <gpx version="1.0" creator="GPSBabel - http://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
  <time>2018-03-23T17:08:07.415Z</time>
  <bounds minlat="36.963316000" minlon="-9.509387000" maxlat="48.885960000" maxlon="4.134580000"/>
  <wpt lat="46.890513000" lon="-2.161012000">
    <ele>0.000000</ele>
    <name>phar-tourelleBoisVinet-ruine-vueDeW</name>
    <cmt>description: &lt;br&gt;categorie: phar</cmt>
    <desc>description: &lt;br&gt;categorie: phar</desc>
  </wpt>
 
  <!-- ETC. -->
 
</gpx>

</body>  <!-- FIN DU FICHIER HTML -->
</html>

On ouvre alors le fichier HTML localement pour voir ce genre de résultat, pour traiter près de 2000 points il faut quelques secondes:

Ficher points.HTML ouvert dans le navigateur

On confirme le message et on ouvre la console avec Ctrl-Alt+J. La console s’ouvre soit dans une nouvelle fenêtre, soit en bas de page.

Ensuite, on clique sur Print DOM et la console se remplit de code XML. Il s’agit de notre fichier GPX final pour OSMAnd, mais il faut encore l’extraire.

Console après génération du contenu GPX

Cliquer d’abord sur Show ... more puis Copy. Le presse-papier contient le fichier GPX final. Il faut encore effacer les quatre premières lignes (marqués en gris en bas) et puis c’est bon à importer sous OSMAnd:

Fichier points.GPX presque final

Attention, en ajoutant des nouveaux „Favoris“ sous OSMAnd avec notre fichier généré, ces nouveaux points s’ajoutent à ceux présents dans /data/net.osmand[.plus]/files/favourites.gpx. Des points avec des noms déjà présents sont affichés avec une numérotation derrière: myPoint (2).

Pour recommencer à zéro il faut soit:

  • effacer les points dans OSMAnd (mais cela ne marche que catégorie par catégorie et peut être long),
  • fermer OSMAnd complètement (plus de signe d’enregistrement de tracks en haut), effacer le fichier favourites.gpx et le remplacer sous le même nom par notre fichier généré.

Traitement des lignes (Path)

OSMAnd est ici embêtant, il n’y a pas moyen de différencier des lignes si on les importe en bloc dans un seul fichier GPX. Elles sont affichées toutes en rouge et on ne peut pas en identifier en tentant d’en sélectionner une. Cela va bien avec une ligne isolée, mais dans le cas de plusieurs tracés de randonnée partant du même points ou se recoupant, on ne dissocie plus rien.

Le seul moyen que j’ai trouvé est de sauvegarder les lignes une par une ce qui est fastidieux. Je les laisse donc ensemble dans le fichier paths.GPX et je les traite par un fichier Perl. Cela marche aussi avec d’autres types de scripts, mais j’avais un bout de code sous la main. Le fichier ressemble à ceci:

$infile = "./paths.gpx";
open(INFILE, "<",$infile) or die "Can't open input $infile: $!\n";
$header = "";
$track = "";
$name = "";
while (<INFILE>) { # PARCOURIR TOUT LE FICHIER
  $line = $_;
  # COPIER LA TÊTE DE FICHIER GPX POUR LA RÉUTILISER DANS TOUS LES FICHIERS INDIVIDUELS
  if ($line =~ m/xml / || $line =~ m/^\<gpx/ || $line =~ m/^\s+\<time/ || $line =~ m/^\s+\<time/ || $line =~ m/^\s+\<bounds/){
    $header .= $line;
  }
  # COPIER UN PATH (TRKSEG) LIGNE PAR LIGNE
  if ($line =~ m/^\s+\<trk\>/ || $line =~ m/^\s+\<name\>/ || $line =~ m/^\s+\<trkseg\>/ || $line =~ m/^\s+\<trkpt/ || $line =~ m/^\s+\<ele\>/ || $line =~ m/^\s+\<\/trk\>/ || $line =~ m/^\s+\<\/trkpt\>/ || $line =~ m/^\s+\<\/trkseg\>/ ){
    $track .= $line;
  }
  # IDENTIFIER ET UTILISER LE NOM (NAME), OUVRIR LE FICHIER SOUS CE NOM ET Y ECRIRE L'ENTÊTE
  if ($line =~ m/^\s+\<name/){
    $line =~ /\<name\>(.+)\<\/name\>$/;
    $name = $1.".gpx";
    open(TRKFILE,">",$name) or die "Can't open output trkfile: $!\n";
    print TRKFILE $header;
  }
  # ECRIRE LE PATH DANS LE FICHIER DESTINATAIRE ET LE FERMER
  if ($line =~ m/^\s+\<\/trk>/){
    print TRKFILE $track;
    print TRKFILE "</gpx>"; # FERMER LE FICHIER
    $track = "";
    close(TRKFILE);
  }
}
close(INFILE);

Les fichiers GPX ainsi générés se placent sous /data/net.osmand[.plus]/files/tracks/import/ et peuvent ensuite être sélectionnés et affichés comme des tracés enregistrés directement sur le portable.

No Comments

Leave a Comment

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.