library(leaflet) # est une librairie initialement en javascript qui permet de faire des cartes dans R
library(htmltools) # permet de créer des pages html à partir de graphiques réalisés avec R
library(WikidataR) # wikidata permet d'encapsuler dans R des requêtes en SPARQL
library(ggplot2) # ggplot2 permet de créer des graphiques avec R
# ci-dessous la requête en sparql envoyée à l'endpoint de Wikidata
# cette requête sélectionne tous les items qui sont des instances (P31) de cimetières de guerre et sont administrés (P625) par la commission des cimetières de guerre allemands (Q708567)
# chaque item est obtenu avec sa localisation (latitude et longitude)
df <- query_wikidata('SELECT DISTINCT ?item ?itemLabel ?coords ?lat ?long
WHERE {
?item p:P31/ps:P31/wdt:279* wd:Q1241568 .
?item wdt:P137 wd:Q708567 .
?item p:P625 ?coords_sample .
{
SELECT (SAMPLE(?coords_stmt) AS ?coords_sample) {
?place p:P31/ps:P31/wdt:279* wd:Q1241568 ;
p:P625 ?coords_stmt .
} GROUP BY ?place
}
?coords_sample ps:P625 ?coords;
psv:P625 [
wikibase:geoLatitude ?lat;
wikibase:geoLongitude ?long
] .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?placeLabel')
df$long <- as.numeric(df$long)
df$lat <- as.numeric(df$lat)
map <- leaflet(df) %>%
# ajoute les tuiles de la carte de base (par défaut OpenStreetMap)
addTiles() %>%
# zjoute les noms des cimetières et leur localisation dans des popups
addMarkers(lng = ~long, lat = ~lat, popup = ~itemLabel)
save_html(map, "../output/r_map.html")
# sauvegarde la carte dans un fichier en html dans le dossier outputle code de démonstration
Pour cette présentation, nous avons pris le parti d’utiliser comme exemple un code source rédigé dans les deux principaux langages utilisés en recherche : R et Python. Ci-dessous, se trouvent les scripts dans ces deux langages. Il s’agit d’un code source assez basique qui réalise les opérations suivante :
- chargement des packages / librairies nécessaires au fonctionnement du code source
- envoi d’une requête vers Wikidata pour récupérer la liste de tous les cimetières de guerre allemands gérés par une certaine association et leur emplacement (longitude, latitude)
- création d’une carte cliquable comportant les marqueurs pour tous ces cimetières. Lorsqu’on clique sur l’un d’eux, un popup apparaît avec le nom et la localisation du cimetière.

Les résultats de ce code source se trouvent dans le dossier output :
Code R
Code Python
import sys
import folium
from folium.plugins import MarkerCluster
# il y a plusieurs librairies de Python qui peuvent être utilisées pour collecter des données depuis Wikidata. SPARQLwrapper est suggéré par le service query.wikidata lui-même quand on copie la requête depuis ce service en format Python.
# folium est l'équivalent de Leaflet pour Python (Leaflet est une librairie écrite en javascript)
from SPARQLWrapper import SPARQLWrapper, JSON
endpoint_url = "https://query.wikidata.org/sparql" # définit le service query.wikidata comme Sparql endpoint (point d'entrée de requête en sparql)
# ci-dessous la requête en sparql envoyée à l'endpoint de Wikidata
# cette requête sélectionne tous les items qui sont des instances (P31) de cimetières de guerre et sont administrés (P625) par la commission des cimetières de guerre allemands (Q708567)
# chaque item est obtenu avec sa localisation (latitude et longitude)
query = """
SELECT DISTINCT ?item ?itemLabel ?coords ?lat ?long
WHERE {
?item p:P31/ps:P31/wdt:279* wd:Q1241568 .
?item wdt:P137 wd:Q708567 .
?item p:P625 ?coords_sample .
{
SELECT (SAMPLE(?coords_stmt) AS ?coords_sample) {
?place p:P31/ps:P31/wdt:279* wd:Q1241568 ;
p:P625 ?coords_stmt .
} GROUP BY ?place
}
?coords_sample ps:P625 ?coords;
psv:P625 [
wikibase:geoLatitude ?lat;
wikibase:geoLongitude ?long
] .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
ORDER BY ?placeLabel
"""
def get_results(endpoint_url, query):
# Cette fonction utilise la requête sparql pour récupérer les résultats de Wikidata dans un format Json
user_agent = "war_cemeteries/1.0 (belvezedamien@gmail.com)"
sparql = SPARQLWrapper(endpoint_url, agent=user_agent)
sparql.setQuery(query)
sparql.setReturnFormat(JSON)
return sparql.query().convert()
# les requêtes réalisées en REST API en direction de la wikibase doivent contenir un user agent en accord avec la politique des sites de Wikimedia
# cf:https://www.wikidata.org/wiki/Wikidata:REST_API/Authentication
results = get_results(endpoint_url, query)
# les résultats de la requête sparql sont enregistrés dans la variable results
map = folium.Map(location=[47, 1], zoom_start=5)
marker_cluster = MarkerCluster().add_to(map)
# utilise folium pour concevoir une carte centrée sur les coordonnées 47°N, 1°W (France) avec un zoom de 5 (à l'échelle du continent européen)
for result in results["results"]["bindings"]:
item_label = result.get("itemLabel", {}).get("value", "")
latitude = float(result.get("lat", {}).get("value", "0"))
longitude = float(result.get("long", {}).get("value", "0"))
folium.Marker(
location=[latitude, longitude],
popup=item_label
).add_to(marker_cluster)
# pour chaque ligne dans le tableau de données results est créé un marqueur avec les coordonnées géographiques trouvées dans les colonnes long et lat. Le label (nom) de l'item est mis à disposition dans un popup
map.save("../output/python_map.html")
# sauvegarde la carte dans un fichier html dans le dossier output