Vous consultez une page technique concernant le logiciel de gestion Mercator. Celle-ci contient des informations spécifiques destinées aux professionnels de Mercator. Souhaitez-vous être redirigés vers des informations plus générales ?


   Ne plus poser cette question

Géocodage d'adresses

0000002953     -      08/09/2021

Mercator permet de transformer facilement une adresse en coordonnées GPS (latitude, longitude). Pour cela, il faut toutefois souscrire à un service externe. Nous proposons une intégration avec ces fournisseurs :

  • Google Maps 
  • Bing Maps
  • Here

L'API de Mercator contenue dans MercatorTunnel.dll contient ces méthodes :

Zoom
public static double[] GeoCoderGoogle(string key, string info, out string error)
public static double[] GeoCoderBing(string info, out string error)
public static double[] GeoCoderBing(string key, string info, out string error)
public static double[] GeoCoderHere(string key, string info, out string error)

Elles renvoient un tableau contenant deux doubles : le premier étant la latitude, le second correspondant à la longitude. Si une erreur est survenue, ces méthodes renvoient null et le message d'erreur est placé dans la variable error.

Pour Google ou Bing, le paramètre key doit contenir : "key=AIzaXyX7xzZXX0C0Xxx0XXXfXXI0XXxXex123sX", adapté selon l'API key obtenue dans le portail de Google ou de Bing. La première signature de la méthode GeoCoderBing n'est utilisable que si l'option BING_KEY est complétée avec la valeur de la clé (sans "key=").

En ce qui concerne Here, le paramètre key doit contenir "apiKey=XxXz1xXXyyyZZZ12abcdefgh_1234567890azertyuio", adapté selon les paramètres d'API obtenus dans le portail de Here.

Le paramètre "info" doit contenir toute concaténation d'informations jugées pertinentes afin de permettre une géolocalisation la plus précise possible : nom, rue, code postal, ville, pays, ...

Le code ci-dessous montre un customizer client qui met automatiquement à jour les coordonnées GPS d'une fiche client, pour toute nouvelle fiche ou si un des éléments de l'adresse a été modifié. Cet exemple est valable pour un dossier dans lequel on aurait ajouté ces colonnes pour stocker, respectivement, la latitude et la longitude.

alter table CLI add C_LAT float not null default 0 
alter table CLI add C_LONG float not null default 0
Zoom
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Linq;
using MercatorApi;
using MercatorExtensions;
using MercatorUi;
using MercatorDatabase;
using System.Windows.Forms;

// <CompileWithRoslyn />

namespace SigCli
{
    public class Customizer : MercatorUi.ICustomizers.IFormValidateCustomizer
    {
        public bool FormValidateCustomize(Form form)
        {
            MercatorUi.Forms.Sig.SigForm sigForm = (MercatorUi.Forms.Sig.SigForm)form;
            if (string.IsNullOrWhiteSpace(sigForm.CliRecord.C_ID) // nouvelle fiche
                || !sigForm.DataSourceRow["c_adresse"].Equals(sigForm.DataSourceRow["c_adresse", DataRowVersion.Original])
                || !sigForm.DataSourceRow["c_codep"].Equals(sigForm.DataSourceRow["c_codep", DataRowVersion.Original])
                || !sigForm.DataSourceRow["c_ville"].Equals(sigForm.DataSourceRow["c_ville", DataRowVersion.Original])
                )
            {
                MercatorUi.Wait.WaitStatic.WaitWindow("Obtenir la position GPS...");
                var latLng = Api.GeoCoderHere("apiKey=XxXz1xXXyyyZZZ12abcdefgh_1234567890azertyuio", sigForm.CliRecord.C_ADRESSE + " " + sigForm.CliRecord.C_CODEP + " " + sigForm.CliRecord.C_VILLE, out string error);
                MercatorUi.Wait.WaitStatic.WaitClear();
                if (latLng == null)
                {
                    MercatorUi.Dialogs.Stop("Obtenir la position GPS : " + error);
                    return false;
                }
                else
                {
                    sigForm.CliRecord.C_LAT = latLng[0];
                    sigForm.CliRecord.C_LONG = latLng[1];
                    return true;
                }
            }
            return true;
        }
    }
}

Mercator offre aussi la possibilité de disposer de ces fonctionnalités sur le serveur SQL. Cela peut être très pratique pour initialiser les données d'une table existante. Pour disposer de cela, il faut activer les fonctions CLR standards de Mercator. Ceci met à disposition ces fonctions SQL "table" qui existent uniquement en version .net :

  • dbo.GEO_CODER_GOOGLE (@key nvarchar(max), @info nvarchar(max))
  • dbo.GEO_CODER_BING (@key nvarchar(max), @info nvarchar(max))
  • dbo.GEO_CODER_HERE (@key nvarchar(max), @info nvarchar(max))

Les paramètres doivent être composés de façon identique aux indications données plus haut dans cette page. Cette fonction table renvoie toujours un et un seul enregistrement et 3 colonnes :

  • latitude
  • longitude
  • error

Soit les deux premiers sont non null et error sera null. En cas d'erreur, seul error sera non null et contiendra cette erreur.

Pour obtenir une seule adresse :

select * from dbo.GEO_CODER_GOOGLE('key=AIzaXyX7xzZXX0C0Xxx0XXXfXXI0XXxXex123sX','Route d''Andenne, 37 5310 Eghezée')

Pour obtenir les coordonnées correspondant à plusieurs fiches de la table CLI :

select c_id,c_adresse+c_codep+c_ville,latitude,longitude 
from CLI cross apply dbo.GEO_CODER_GOOGLE('key=AIzaXyX7xzZXX0C0Xxx0XXXfXXI0XXxXex123sX',c_adresse+c_codep+c_ville)

Pour mettre à jour des fiches de la table CLI :

update CLI set c_lat=g.latitude,c_long=g.longitude
from CLI cross apply dbo.GEO_CODER_GOOGLE('key=AIzaXyX7xzZXX0C0Xxx0XXXfXXI0XXxXex123sX',c_adresse+c_codep+c_ville) g
where (g.latitude is not null) and (c_lat=0)

Remarques importantes concernant ces requêtes :

  • Appliquer ces requêtes sur un grand nombre d'enregistrements peut très vite épuiser le quota auquel vous avez souscrit chez votre fournisseur
  • Pour chaque enregistrement, la fonction SQL de géocodage va interroger un web service. Il est donc normal que ceci soit "lent". De plus, sur un lot de taille relativement importante, il est normal d'avoir des retours en erreur (latitude et longitude à null). L'erreur étant provoquée par d'éventuels time-outs ou limites de connexion. Il sera donc nécessaire de
    • découper la mise à jour en nombre d'enregistrements de taille modeste
    • d'effectuer plusieurs fois le même update, afin que les enregistrements en erreur puissent finalement obtenir une valeur.
  • Etant donné ce qui précède, il est vigoureusement déconseillé d'utiliser ces fonctions dans un trigger.

 

Mots clés : localisation