Utilisation des APIs cartographiques de l’IGN et du service data.gouv.fr

Laurent Cavallini
5 min readFeb 5, 2021

L’institut National de l’Information Géographique et Forestière (IGN)est une mine d’informations et donc de data. Pour rendre ces données publiques et utilisables ils ont lancé un service d’APIs : https://apicarto.ign.fr/
Si l’on couple ça au service de recherche d’adresses de data.gouv.fr et un fond de carte on peut très rapidement avoir un outil performant pour travailler de manière ludique et intuitive.

Pour Limto (https://limto.io/), une solution d’estimation foncière, j’avais besoin de mettre en place un système de recherche de Plan Local d’Urbanisme (PLU). Ce document régissant les règles d’urbanisme pour une adresse donnée, il est nécessaire à cette application web.

D’un point de vue fonctionnalité, voici le cheminement :

  • On utilise l’API de data.gouv.fr (https://geo.api.gouv.fr/adresse) “search” de recherche d’adresse textuelle pour trouver l’adresse souhaitée.
    Cette recherche nous renvoie les coordonnées GPS (longitude, latitude) de l’adresse en question.
  • On peut faire une recherche inversée en sélectionnant directement sur la carte notre lieu, et donc les coordonnées GPS pour retrouver de façon inversée l’adresse textuelle. Pour cela on utilise l’API, toujours de data.gouv.fr, “reverse”, disponible ici : https://geo.api.gouv.fr/adresse.
  • Grâce à ces coordonnées on va pouvoir trouver la parcelle cadastrale, la zone du PLU concernée et bien sûr, le PLU concerné.
  • Pour la parcelle cadastrale et sa zone urbaine, on utilise l’API Carto GPU (https://apicarto.ign.fr/api/doc/gpu) et plus particulièrement la “zone-urba” qui nous renvoie la zone précise dont fait partie notre adresse.
  • Pour le PLU, le document en lui-même, l’API Carto GPU (https://apicarto.ign.fr/api/doc/gpu) a un autre service dédié : “document”.

Pour récapituler je vous fais une démo directement sur Limto, je saisis une adresse et j’attends que les APIs fassent leur travail et me présente :

  • L’adresse textuelle
  • La localisation sur la carte
  • La zone urbaine dont dépend l’adresse
  • La zone délimitée sur la carte
  • le PLU pdf lié qui va me donner toutes les infos sur cette parcelle

On peut jouer avec la carte et cliquer sur différentes adresses qui se recherchent automatiquement très rapidement.

Pour les non développeurs, l’article s’arrête ici. Je voulais présenter simplement la puissance qu’offre la combinaison de différentes APIs disponibles gratuitement.

D’un point de vue développeur, voici la marche à suivre :

La première étape consiste à mettre en place un champ de recherche d’adresse, pour cela on a du HTML, je me sers de class “js-…” comme sélecteur JS/jQuery :

<input class="js-search ui-autocomplete-input" name="address" type="text" autocomplete="off">

Maintenant on rajoute du code JS/jQuery pour appliquer la recherche via l’API et un système d’autocomplete. L’API https://api-adresse.data.gouv.fr/search/ permet de rechercher une adresse textuelle, on récupère les coordonnées GPS (longitude, lattitude) :

$('.js-search').autocomplete({
source: function(request, response)
{
$.ajax({
url : "https://api-adresse.data.gouv.fr/search/",
dataType : 'json',
data : {
q: request.term,
autocomplete : 1
},
success: function(result)
{
response($.map(result.features, function(object)
{
return {
label: object.properties.label,
geometry: object.geometry
};
}));
}
});
},
select: function(event, ui)
{
$('.js-geometry').val(JSON.stringify(ui.item.geometry));
$('.js-longitude').val(ui.item.geometry.coordinates[0]);
$('.js-latitude').val(ui.item.geometry.coordinates[1]);
}
});

Une fois ces coordonnées récupérées, on peut récupérer le PLU, la zone dont dépend la parcelle et les délimitations de la zone :

currentRequestZoning = $.ajax({
timeout: 5000,
url : "https://apicarto.ign.fr/api/gpu/zone-urba/",
dataType : 'json',
data : {
geom: JSON.stringify(geometry),
},
beforeSend: function()
{
if(currentRequestZoning != null)
{
currentRequestZoning.abort();
}
$('.js-zoning-table').html(svg);
$('.js-zoning_file-table').html(svg);
},
success: function(result)
{
if (isEmpty(result.features))
{
$('.js-zoning-table').text('-');
$('.js-zoning').val('');
$('.js-zoning_file-table').text('-');
$('.js-zoning_file').val('');
}
else
{
var geojsonFeature = result.features[0];
var jsonLayer = L.geoJSON(geojsonFeature);
dataLayer.addLayer(jsonLayer);
map.flyToBounds([
[result.bbox[1], result.bbox[0]],
[result.bbox[3], result.bbox[2]]
]);
if (geojsonFeature.hasOwnProperty('properties') && geojsonFeature.properties.libelle)
{
$('.js-zoning').val(geojsonFeature.properties.libelle);
$('.js-zoning-table').html(geojsonFeature.properties.libelle);
}
else
{
$('.js-zoning').val('');
$('.js-zoning-table').html('-');
$('.js-zoning_file-table').text('-');
}
if (geojsonFeature.hasOwnProperty('properties') && geojsonFeature.properties.nomfic)
{
getDocument(geometry, geojsonFeature.properties.nomfic);
}
else
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
}
},
error: function(xmlhttprequest, textstatus, message)
{
$('.js-zoning-table').text('-');
$('.js-zoning_file-table').text('-');
}
});

Voici les fonctions qui vont permettre de récupérer le document et son contenu :

function getZoningValue(geometry)
{
currentRequestZoning = $.ajax({
timeout: 5000,
url : "https://apicarto.ign.fr/api/gpu/zone-urba/",
dataType : 'json',
data : {
geom: JSON.stringify(geometry),
},
beforeSend: function()
{
if(currentRequestZoning != null)
{
currentRequestZoning.abort();
}
$('.js-zoning-table').html(svg);
$('.js-zoning_file-table').html(svg);
},
success: function(result)
{
if (isEmpty(result.features))
{
$('.js-zoning-table').text('-');
$('.js-zoning').val('');
$('.js-zoning_file-table').text('-');
$('.js-zoning_file').val('');
}
else
{
var geojsonFeature = result.features[0];
var jsonLayer = L.geoJSON(geojsonFeature);
dataLayer.addLayer(jsonLayer);
map.flyToBounds([
[result.bbox[1], result.bbox[0]],
[result.bbox[3], result.bbox[2]]
]);
if (geojsonFeature.hasOwnProperty('properties') && geojsonFeature.properties.libelle)
{
$('.js-zoning').val(geojsonFeature.properties.libelle);
$('.js-zoning-table').html(geojsonFeature.properties.libelle);
}
else
{
$('.js-zoning').val('');
$('.js-zoning-table').html('-');
$('.js-zoning_file-table').text('-');
}
if (geojsonFeature.hasOwnProperty('properties') && geojsonFeature.properties.nomfic)
{
getDocument(geometry, geojsonFeature.properties.nomfic);
}
else
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
}
},
error: function(xmlhttprequest, textstatus, message)
{
$('.js-zoning-table').text('-');
$('.js-zoning_file-table').text('-');
}
});
}
var currentRequestDocument = null;function getDocument(geometry, filename)
{
currentRequestDocument = $.ajax({
timeout: 10000,
url : "https://apicarto.ign.fr/api/gpu/document/",
dataType : 'json',
data : {
geom: JSON.stringify(geometry),
},
beforeSend: function()
{
if(currentRequestDocument != null)
{
currentRequestDocument.abort();
}
},
success: function(result)
{
if (isEmpty(result.features))
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
else
{
var geojsonFeature = result.features[0];
if (geojsonFeature.hasOwnProperty('properties') && geojsonFeature.properties.id)
{
getDocumentUrl(geojsonFeature.properties.id, filename);
}
else
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
}
},
error: function(xmlhttprequest, textstatus, message)
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
});
}
var currentRequestDocumentUrl = null;function getDocumentUrl(docId, filename)
{
currentRequestDocumentUrl = $.ajax({
timeout: 10000,
url : "https://www.geoportail-urbanisme.gouv.fr/api/document/"+docId+"/details",
dataType : 'json',
beforeSend: function()
{
if(currentRequestDocumentUrl != null)
{
currentRequestDocumentUrl.abort();
}
},
success: function(result)
{
if (result == "Aucun Document trouv\u00e9")
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
else
{
if (result.hasOwnProperty('writingMaterials') && result.writingMaterials.hasOwnProperty(filename))
{
$('.js-zoning_file').val(result.writingMaterials[filename]);
$('.js-zoning_file-table').html('<a href="'+result.writingMaterials[filename]+'" target="_blank"><img src="{{ asset('images/Download-white.svg') }}" style="width:30px;" /></a>');
}
else if (result.hasOwnProperty('archiveUrl'))
{
$('.js-zoning_file').val(result.archiveUrl);
$('.js-zoning_file-table').html('<a href="'+result.archiveUrl+'" target="_blank"><img src="{{ asset('images/Download-white.svg') }}" style="width:30px;" /></a>');
}
else
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').html('-');
}
}
},
error: function(xmlhttprequest, textstatus, message)
{
$('.js-zoning_file').val('');
$('.js-zoning_file-table').text('-');
}
});
}

--

--