# applescript : convertir latitude longitude en adresse postale ?



## two (23 Avril 2017)

Bonjour, 

j'ai un applescript qui me permet de créer de nouveaux contacts dans mon carnet d'adresse sur base d'un fichier XML (qui m'est fourni et sur lequel je n'ai pas la main)
Tout va bien tant pour la lecture du fichier XML que pour la création des contacts. 

La ou je coince c'est que le fichier XML ne me fournit pas d'adresse postale mais un point géographique dans le format suivant :  48.858372,2.294479 ( pour l'exemple, la tour Eiffel)
Mon soucis est que si je l'importe comme cela je ne peux pas utiliser la fiche de contact pour lancer un itineraire   ni sur iOs (sur OsX cela marche... ) ni sur le GPS embarqué de mon véhicule (il accède aux contacts du smartphone).

Google n'est, pour une fois, pas mon ami. 
Auriez vous une piste à me donner pour me permettre de m'approcher de mon objectif?


----------



## zeltron54 (23 Avril 2017)

Bonjour,
En entrant les coordonnées GPS tu peux récupérer l'adresse postale sur cette page : https://www.coordonnees-gps.fr/
Tu saisis tes coordonnées et tu cliques sur Obtenir l'adresse !


----------



## two (23 Avril 2017)

Salut Zeltron,

effectivement, mes recherches m'avaient mené sur ce site.
Vu le nombre et la fréquence des conversions auxquelles je vais être confronté, j'aimerais toutefois trouver le moyen d'automatiser un peu la chose.
J'avais également trouvé ce site : http://www.gpsfrance.net/coordonnees-gps-vers-liste-adresses
j'ai envisagé passer par  remplir  le presse papier d'une liste raisonnable de résultats  pour le coller manuellement sur le site mais le soucis c'est que la page empêche de  sélectionner  et/ou copier le résultat obtenu.



Cet après midi j'ai également trouvé ce site : http://wiki.openstreetmap.org/wiki/Nominatim
Ce qui fait que j'ai déjà pu coder ceci :

```
set myLAT to "48.858372"
set myLON to "2.294479"

set HTMLfirst to "http://nominatim.openstreetmap.org/reverse?format=xml&lat="
set HTMLmiddle to "&lon="
set HTMLlast to "&zoom=18&addressdetails=1"

set myHTML to HTMLfirst & myLAT & HTMLmiddle & myLON & HTMLlast
open location myHTML
```

ma question évolue donc en celle-ci : que dois, mettre à la place ou après "open location myHTML" pour récuperer le xml généré par la page  (une fois ceci fait  ce ne sera pas un soucis pour définir les variables "rue" "CP" "Localité" et "pays" nécessaires à la création de fiches de contact)?


----------



## zeltron54 (23 Avril 2017)

Tu as différentes solutions !

1 - la plus simple: Avec le site gpsfrance  Tu fais, comme tu l'as mentionné, un copier coller de tes coordonnées, tu affiches les adresse, puis dans ton Navigateur (Safari ou Firefox ou ....) dans les menus tu affiche le code source de la page et là il est très facile de faire un copier coller des adresses.

2 - Tu exécutes ton script auquel tu ajoutes la récupération du code source de la page que tu "sparses" le fichier obtenu pour récupérer les données.
ci dessous un copier coller des éléments (exemple)
addressparts>
<attraction>Tour Eiffel</attraction>
<house_number>5</house_number>
<pedestrian>Avenue Anatole France</pedestrian>
<suburb>Quartier du Gros-Caillou</suburb>
<city_district>Paris 7e Arrondissement</city_district>
<city>Paris</city>
<county>Paris</county>
<state>Île-de-France</state>
<postcode>75007</postcode>
<country>France</country>
<country_code>fr</country_code>
</reversegeocode

Mais la solution 1 me semble bien plus simple .


----------



## two (23 Avril 2017)

Je me réponds à moi-même, sur base de cette page : https://forums.macrumors.com/threads/applescript-question-extracting-data-from-websites.1656735/
voici un code fonctionnel:

```
set myLAT to "48.858372"
set myLON to "2.294479"

set HTMLfirst to "http://nominatim.openstreetmap.org/reverse?format=xml&lat="
set HTMLmiddle to "&lon="
set HTMLlast to "&zoom=18&addressdetails=1"

set myHTML to HTMLfirst & myLAT & HTMLmiddle & myLON & HTMLlast

tell front window of application "Safari"
    --Create a new page and get its source
    set theTab to make new tab with properties {URL:myHTML}
    delay 3 --give the page a bit of time to load (crude method)
    set theSource to source of theTab
  
    --Find the stock price by finding the text between <span id="yfs_l84_aapl"> and </span> in the page's source
    set myhouse_number to my textBetween(theSource, "<house_number>", "</house_number>")
    set myroad to my textBetween(theSource, "<road>", "</road>")
    set mypedestrian to my textBetween(theSource, "<pedestrian>", "</pedestrian>")
    set mycity to my textBetween(theSource, "<city>", "</city>")
    set myzip to my textBetween(theSource, "<postcode>", "</postcode>")
    set myadress to myhouse_number & ", " & myroad & mypedestrian & " - " & myzip & " " & mycity
  
    close theTab
    return myadress
  
end tell

on textBetween(searchText, startText, endText)
    set defaultDelims to AppleScript's text item delimiters
    set AppleScript's text item delimiters to startText
    if (count of text items of searchText) is 1 then return "" -- no match for startText
    set searchText to second text item of searchText
    set AppleScript's text item delimiters to endText
    if (count of text items of searchText) is 1 then return "" -- no match for endText
    set searchText to first text item of searchText
    set AppleScript's text item delimiters to defaultDelims
    return searchText
end textBetween
```


----------



## JacqR (24 Avril 2017)

Bonjour,


Pour ne pas utiliser un navigateur et avoir un "delay 3", vous pouvez récupérer la source avec la commande *curl*:

```
set myLAT to "48.858372"
set myLON to "2.294479"
set theSource to do shell script "curl " & quoted form of ("http://nominatim.openstreetmap.org/reverse?format=xml&lat=" & myLAT & "&lon=" & myLON & "&zoom=18&addressdetails=1")
```


--
Comme vous l'avez remarqué (dans le XML de *openstreetmap.org*), le nom de la rue sera peut-être dans le tag <road> ou <pedestrian>, il y a aussi pour la localité qui sera dans le tag <city> ou <village>, et il y a peut-être d'autres différences.

Voici une solution (AppleScript) qui utilise "maps.googleapis.com", les noms des tags sont toujours les mêmes, donc c'est *php* qui récupère les valeurs dans le texte au format JSON


```
set myLAT to "48.858372"
set myLON to "2.294479"

set scriptPHP to quoted form of "$myVals = array(\"street_number\" => \"\", \"route\" => \"\", \"postal_code\" => \"\", \"locality\" => \"\", \"country\" => \"\");
$myTypes = array(\"street_number\", \"route\", \"locality\", \"country\",\"postal_code\");
$a=json_decode(file_get_contents($argv[1]))->results[0]->address_components;
if ($a) {foreach($a as $i) {$t = $i->types[0]; if (in_array($t , $myTypes)) $myVals[$t] = $i->long_name;}}
print implode(\"\\n\", $myVals);"

set r to do shell script "/usr/bin/php -r  " & scriptPHP & " " & quoted form of ("http://maps.googleapis.com/maps/api/geocode/json?latlng=" & myLAT & "," & myLON & "&sensor=false") without altering line endings
set {numero, rue, CP, localite, pays} to paragraphs of r
```


Si vous préférez un script plus facile à comprendre que le script en *php* (*curl* récupère le texte au format XML au lieu du format JSON):


```
set myLAT to "48.858372"
set myLON to "2.294479"
set {numero, rue, localite, pays, CP} to {"", "", "", "", ""}

set myXML to do shell script "curl " & quoted form of ("http://maps.googleapis.com/maps/api/geocode/xml?latlng=" & myLAT & "," & myLON & "&sensor=false")
if "<address_component>" is in myXML then --ce tag existe dans le texte
    tell application "System Events"
        set d to make new XML data with data myXML
        tell (XML elements of XML element "result" of XML element 1 of d whose name is "address_component")
            repeat with i in it
                set t to value of XML element "type" of i -- on obtient le premier élément "type" dans l'élément "address_component" (route, locality, etc..), certain élément contiennent plusieurs types
                set v to value of XML element "long_name" of i -- on obtient la valeur de cet élément (le nom de la rue par exemple)
                if t is "street_number" then
                    set numero to v
                else if t is "route" then
                    set rue to v
                else if t is "country" then
                    set pays to v
                else if t is "postal_code" then
                    set CP to v
                else if t is "locality" then
                    set localite to v
                end if
            end repeat
        end tell
    end tell
    set myadress to numero & ", " & rue & " - " & CP & " " & localite & ", " & pays
end if
```


----------



## two (25 Avril 2017)

JacqR a dit:


> Si vous préférez un script plus facile à comprendre que le script en *php* (*curl* récupère le texte au format XML au lieu du format JSON):


Bonjour JacqR


Comme tu t'en doutais je me suis tourné vers ton troisième script. 
C'est nettement plus rapide que ce que j'avais fait.
Un grand merci pour ton aide.


----------

