Archives pour la catégorie Web

La Touraine en latin

Le français n’a pas toujours été la langue de la France. Sans parler des langues d’oc, germaniques, celtiques, basques, la Touraine passe pour pratiquer un très bon français (comprendre « très semblable au parler de Paris »)

Cependant, au haut moyen-âge, on y parlait apparemment une forme de
latin vulgaire assez barbare et bien éloigné de celui de Cicéron. Les
anciens noms des villes et villages tourangeaux sont néanmoins connus
par des manuscrits latins (la langue écrite des ecclésiastiques et des
lettrés). Ce sont généralement des livres d’histoire ou des chartes
monastiques énumérant les biens de telle ou telle communauté.

J’ai pu trouver ces anciens noms dans le Dictionnaire des communes d’Indre-et-Loire, une encyclopédie spécialisée et très complète qu’on peut consulter dans les bibliothèques municipales locales.

Les noms en latin sont inscrits dans OpenStretMap, avec la clé name:la. L’extraction des données a été obtenue grâce à Overpass API, et la carte a été générée et mise en forme sur l’excellente plateforme umap. Il suffit de cliquer sur les points bleus pour voir les noms en latin et en français.

Voir en plein écran

English : The map above displays the latin names of
municipalities in the departement Indre-et-Loire, in the centre of
France. Those ancient names are known thanks to medieval history books
and monastic charters. I have found them in Dictionnaire des communes d’Indre-et-Loire, a specialised encyclopedia, and added them to OpenStreetMap. I have extracted the data with Overpass API, and the map was created with umap. The maps displays the latin names (italic), along with modern French names (bold), when you click the blue dots.

petiteReine, une visualisation des parkings vélo avec OpenStreetMap

Un besoin

En octobre 2014 a commencé une collaboration entre le Collectif cycliste 37 et Tour(s) plus pour répertorier les parkings vélo de plusieurs communes de l’agglomération tourangelle. Ceci répondait aux besoins des deux parties : la collectivité n’avait pas de bases de données de ces équipements et l’association cherchait à diagnostiquer les besoins en stationnement sur l’agglomération. Culture libre et créations collectives s’est associée à cette initiative, d’où ma propre implication.

Quatre jours de cartopartie ont permis d’identifier 859 parkings sur les communes de Tours et Joué-les-Tours, mais comment visualiser ces données dans un outil grand public sur la toile ? comment tirer du sens d’un nuage de points sur une carte ?

La carte cyclable du site openstreetmap.org présente des carrés bleus pour les parkings vélo, les parkings de grande capacité ont un marqueur différent (un C dans un carré, accompagné de la capacité). Ce rendu est très sommaire car il n’informe du nombre de places que pour une petite minorité de stationnement, qu’il ne différencie par les équipements ouverts au public de ceux qui sont privés, et qu’il affiche identiquement les arceaux et les pince-roues, quand bien même les cyclistes préfèrent largement les premiers aux seconds (pour des raisons de sécurité). Le service de calcul d’itinéraires Géovélo affiche lui aussi les parkings vélo sur la carte, aux niveaux de zooms les plus hauts, mais le but est de montrer une information complémentaire (des stationnements situés dans les environs) à des cyclistes qui viennent calculer un itinéraire.

J’ai donc décidé de développer une petite application qui permettrait la visualisation des parkings vélo, l’analyse des données et le contrôle qualité.

Voir la carte.

Consultation détaillée

Le premier objectif est d’afficher les parkings vélos avec toutes les informations utiles aux cyclistes, dans une info-bulle qui s’affiche quand on passe la souris. Chacune de ces informations vient d’un attribut des objets décrits dans OpenStreetMap

  • Quel est le type ? On a seulement trois types sur notre territoire, les arceaux, les pince-roues et les abris (clé bicycle_parking)
  • Combien de vélos peut-on garer ? (clé capacity)
  • Est-ce que l’emplacement est couvert ? (clé covered)
  • Le lieu est-il accessible au public ? réservé aux clients ou usagers ? ou bien privé ? (clé access)
  • Quand des restrictions d’accès s’appliquent, à qui appartient le stationnement (clé operator) ? Cela peut être une entreprise qui pose des emplacements pour ses salariés, ou un commerce qui fournit ce service à sa clientèle.

Analyse de données

L’application petiteReine est avant tout un outil d’analyse des données sur les parkings vélo, qui peut servir aux associations cyclistes, aux collectivés, aux citoyens. Elle permet la visualisation des parkings vélo et le diagnostic sur la couverture du territoire en stationnements.

L’analyse se fait selon trois dimensions.

L’espace (où sont les parkings ?)

La prise en compte de l’espace est centrale dans un outil cartographique. Il est pris en compte de différentes manières à différents niveaux :

  • À petite échelle, on peut voir la localisation la plus exacte possible des stationnements vélo
  • À une échelle plus grande, les parkings sont regroupés en grappes ; on peut voir l’étendue de chaque grappe en passant la souris sur le symbole circulaire
  • Au niveau des divisions administratives, on a la possibilité de filtrer les données par commune
  • On peut également constater la répartition physique des parkings vélo sur le territoire avec la couche « Couverture en parkings vélo », qui affiche en vert les zones bien couvertes en stationnements (à moins de 100 mètres d’un parking vélo), et montre des zones plus éloignées (jaune entre 100 et 200m , orange de 200 à 400m). Ceci permet notamment de mettre en avant les zones où la couverture est dense, et les zones blanches.
  • Au niveau d’un point quelconque de la carte, un clic permet de déterminer la distance à vol d’oiseau jusqu’au parking le plus proche

La quantité (est-ce qu’il y en a assez ?)

Afficher des points sur une carte permet de vérifier la présence ou l’absence de parkings à un endroit. Il est intéressant de connaitre le nombre de places, au niveau d’un parking, mais aussi à plus grande échelle. C’est pour cela que les regroupements de parkings affichent le nombre total de places dans la zone du regroupement.

Dans le bloc des statistiques, on reprend le nombre de parkings et de places au niveaux des communes actuellement affichées.

Au delà de la maille de la commune, on peut déterminer une zone (quartier, voie de circulation) dans laquelle, on fait un comptage des parkings et places de stationnement. Le tracé de zones peut se faire par rectangle ou par polygone.

La typologie des parkings

La consultation individuelle d’un parking vélo met avant tout en valeur son type parmi les trois types identifiés sur Tours : arceaux, pince-roue et abri

Les statistiques proposées par l’outil permettent de compter les stationnements et places disponibles sur une zone donnée, mais on s’intéresse également au type des parkings en affichant des sous-totaux par type.

Veiller à la qualité

Puisqu’on récupère l’ensemble des parkings vélo sur une zone pour présenter des statistiques, on peut sans peine effectuer une validation simple et automatique des données présentes (mais pas deviner la présence sur le terrain de parkings inconnus dans OpenStreetMap). Alors qu’OpenStreetMap laisse la liberté de décrire un objet géographique, même de manière très incomplète, nous pensons que pour chaque parking, on doit au moins connaître le type de stationnement (arceau, pince-roue,…) et le nombre de places.

Un couche cartographique présente l’ensemble des parkings qui présentent au moins un de ces défauts :

  • Nombre de places inconnu
  • Type inconnu
  • Doublon géographique (deux parkings aux mêmes coordonnées, même si deux parkings voisins existent, ils doivent être distincts dans l’espace)

Le fait de présenter des données à corriger est une motivation pour des contributeurs d’OpenStreetMap, qui vont chercher à faire disparaitre ces signalements en corrigeant les données. Les marqueurs sont accompagnés d’un lien permettant de modifier ces données dans JOSM (éditeur de données OpenStreetMap). Si des parkings manquant d’informations sont ajoutés par la suite, ils seront aussi signalés.

La rapidité de mise à jour fait partie de la culture d’OpenStreetMap, les contributeurs souhaitent voir apparaitre les résultats de leurs modification sans attendre un processus de validation ou une synchronisation qui se produit rarement. La mise à jour des données de la carte se fait donc toutes les heures. Un traitement planifié récupère l’ensemble des données en parkings vélo de la zone, grâce à un service nommé Overpass API, qui extrait des données d’OpenStreetMap à la demande. Lors d’une cartopartie, on peut donc voir rapidement les résultats de la collecte, mais si d’autres utilisateurs d’OpenStreetMap ajoutent des données inexactes ou incomplètes cela sera visible rapidement.

Essaimer

Sur d’autres territoires

Après quelques dizaines d’heures de développement, j’ai réalisé qu’il serait dommage d’avoir passé tant de temps pour un outil qui ne servirait que pour un territoire, ses citoyens et ses collectivités.

Il était assez logique de publier le logiciel sous forme de logiciel libre (licence AGPL), sur la plateforme GitHub. Et non seulement faut-il mettre le logiciel à disposition, mais il faut le rendre accessible ; une documentation d’installation est disponible, pour guider toute personne ayant des compétences en informatique qui voudrait déployer l’application sur son propre serveur et sur le territoire de son choix. Le but de cette documentation est de rendre la carte installable rapidement, sur un hébergement peu cher et sans nécessiter de compétences très pointues.

Actuellement, les outils requis sont PHP et PostGIS. Il n’est pas possible à ma connaissance de disposer de PostGIS sur des hébergements mutualisés, mais on peut très bien se baser sur des serveurs dédiés ou des serveurs privés virtuels à faible coût (ex : VPS à partir de 2€ HT par mois chez OVH).

Pour maximiser les chances de réutilisation à l’échelle internationale, la documentation est écrite en anglais (enfin, en cours d’écriture). L’application offre également le support de plusieurs langues : anglais et français sont disponibles pour le moment, mais l’ajout d’autres langues peut se faire assez facilement. Les textes affichés à l’écran font partie de la configuration ; si par exemple des réutilisateurs francophones reprennent l’outil et veulent simplement changer des libellés ou la terminologie (exemple : Communes en Arrondissements si on fait une carte sur Paris), ceci nécessite simplement de modifier un fichier de configuration, sans avoir de compétences techniques.

Vers un outil plus global ?

Si le besoin émerge d’afficher des parkings vélo à une échelle plus grande (pays, monde), l’évolution est envisageable, mais nécessitera des moyens supérieurs en termes d’infrastructure.

La magie du regroupement dans OpenLayers

Quand on affiche tout un tas de points d’intérêts sur une carte, leur répartition n’est pas toujours uniforme, ce qui occasionne parfois un agglutinement des points d’intérêt qui s’empilent dans une mêlée confuse.

Pour gérer proprement des points d’intérêt nombreux et qui ont tendance à se confondre, on dispose dans OpenLayers d’un mécanisme de regroupement, qu’on désigne en anglais sous le nom de clustering. Plutôt que dessiner tous les points tel quel, la bibliothèque va se charger de regrouper les points très rapprochés en un seul point d’intérêt. Ce système, bien que puissant est un peu compliqué, comme bien d’autres choses dans OpenLayers.

Voyons point par point comment mettre en œuvre le regroupement sur une couche de points, gérer l’apparence des points regroupés et prendre en compte les événements sur une telle couche.

Propriétés de la couche

Le regroupement dans OpenLayers est implémenté comme une stratégie, c’est à dire un objet qui change de comportement d’une couche. Voici la définition de notre couche de point d’intérêt, un objet OpenLayers.Strategy.Cluster() est fourni dans la propriété strategies.

var layerPOI = new OpenLayers.Layer.Vector("Points d'intérêt", {
	projection: new OpenLayers.Projection("EPSG:4326"),
	strategies: [
		new OpenLayers.Strategy.Cluster()
	],
	styleMap:new OpenLayers.StyleMap({
           "default": clusterStyle
	})
});

Nota: Nous avons référencé un style nommé clusterStyle, que nous expliciterons plus tard.

Manipuler les groupes

Il est nécessaire ici d’adapter votre code concernant la gestion des événements liés à la couche. Quand on implémente un contrôle, comme SelectFeature pour intercepter le clic sur un objet, sans regroupement d’objets, on reçoit un objet OpenLayers.Vector, dont les propriétés sont:

  • attributes:  tableau des attributs de l’objets
  • geometry: une géométrie

Quand on ajoute à cela le regroupement, on reçoit plus des OpenLayers.Vector, mais un objet avec deux attributs:

  • count: nombre de points d’intérêt dans le groupe
  • cluster: tableau des objets du groupe, ce sont des OpenLayers.Vector

Re-définir le style

Pour la couche, on doit définir un style avec la classe OpenLayers.Style. Comme dans toutes les déclarations de style dans OpenLayers, on y définit les valeurs de différents attributs comme le label, la grosseur d’un point ou l’adresse d’un pictogramme. Mais comme on ne souhaite pas forcément rendre un point d’intérêt seul de la même manière que le regroupement de dix points d’intérêt, on peut calculer des propriétés de style en fonction du groupe de points d’intérêt. Là où on donne souvent des valeurs constantes pour une propriété, on peut déclarer dans les attributs des « variables ». Par exemple, dans la propriété label, on utilise la déclaration ${nombre}, qui désigne une valeur à calculer lors du rendu de la couche. Les variables sont calculées dans des méthodes du même nom, qui font partie de l’objet context.

Dans cet exemple, on affiche comme label le nombre d’éléments d’un groupe d’au moins deux éléments, avec la variable ${nombre}.

var clusterStyle = new OpenLayers.Style({
    label:"${nombre}",
    graphicWidth: 20,
    graphicHeight: 20
}, {
    context: {
         nombre: function(feature) {
             if(feature.attributes.count>=2)
            	 return feature.attributes.count;
             else
            	 return "";
         }
    }
});

Critères de regroupement

L’algorithme de regroupement d’OpenLayers est relativement simple: on regroupe tous les objets qui, à l’écran, sont à moins de 40 pixels de distance.

On peut vouloir personnaliser ce comportement, pour prendre en compte d’autres règles de gestion. Dans ce cas, après avoir instancié la stratégie de regroupement, on doit re-définir sa méthode shouldCluster. Partant d’un groupe existant, nommé cluster et d’un objet feature qu’on pourrait y ajouter, cette méthode décide de la possibilité de fusionner le groupe avec un élément, en retournant un booléen. Dans cet exemple, on a modifié la stratégie pour ne regrouper que les objets qui ont la même valeur pour l’attribut type et qui sont distant d’au plus 35 pixels.

var clusterCat = new OpenLayers.Strategy.Cluster();
clusterCat.shouldCluster = function(cluster,feature)
{
	if(cluster.cluster[0].attributes.type != feature.attributes.type)
	{
		return false;
	}
	var cc = cluster.geometry.getBounds().getCenterLonLat();
        var fc = feature.geometry.getBounds().getCenterLonLat();
        var distance = (Math.sqrt(Math.pow((cc.lon - fc.lon), 2) + Math.pow((cc.lat - fc.lat), 2)) / this.resolution);
        return (distance <= 35);
}

Valeur par défaut dans un champ texte avec jQuery

Dans les formulaires sur le web, on trouve souvent des champs texte qui affichent au départ une petite explication sur ce que l’utilisateur doit y taper. Le texte par défaut est souvent dans un ton gris qui signifie qu’il s’agit simplement d’une indication. Quand on entre dans le champ texte, la couleur du texte change. Et si jamais on quitte le champ texte en le laissant vide, la valeur par défaut revient avec son apparence originelle.

Petite démo:

Ce comportement est déjà implémenté dans les navigateurs modernes grâce à l’attribut placeholder de HTML5, malheureusement, quand il faut assurer la compatibilité avec tous les navigateurs, dont le vénérable et sénile Internet Explorer 7, HTML5 ne peut pas tout.

Voici de quoi mettre en œuvre cet effet très simplement avec jQuery.

On définit premièrement deux classes CSS:

  • inputValDefaut définit l’apparence du champ texte quand il a sa valeur par défaut
  • inputValDefautValeur est utilisé pour représenter le champ si l’utilisateur y a entré une valeur

Ici, la valeur par défaut sera en gris et les valeurs réelles en noir.

.inputValDefaut{color: #aaaaaa}
.inputValDefautValeur{color: black}

On déclare ensuite un ou plusieurs champs texte avec la classe inputValDefaut, et on utilise l’attribut title pour la valeur par défaut.

<input type="text" title="Taper une adresse" name="adresse" class="inputValDefaut">

Il ne reste plus qu’à copier-coller ces quelques lignes de Javascript, qui gèrent le changement d’état des champ texte et affecte leurs valeurs par défaut.

$(function(){
    	$(".inputValDefaut").bind({
    		blur:function(){
    			if($(this).val() == "")
    			{
    				$(this).val($(this).attr("title"));
    				$(this).removeClass("inputValDefautValeur");
    			}
    		},
    		focus:function(){
    			if($(this).val() == $(this).attr("title"))
    			{
    				$(this).val("");
    				$(this).addClass("inputValDefautValeur");
    			}
    		}
    	});
    	$(".inputValDefaut").each(function(){$(this).val($(this).attr("title"))});
});