[OSM-talk-fr] téléchargement d'une zone trop grande

Philippe Verdy verdy_p at wanadoo.fr
Mer 22 Fév 17:27:23 UTC 2012


Le 22 février 2012 15:44, sukran.geo sukran.geo <sukran.geo at live.fr> a écrit :
>
> Bonjour,
>
> J'ai une zone dans OSM que je veux télécharger, mais... apparemment, elle
> est trop grande, et voici le message qui s'affiche. (voir JPEG Joint) J'ai
> ensuite téléchargé le fichier de Geofabrik, mais idem, pb de taille.
>
> Que faire ? Il me faut toute la zone, et je ne veux pas pas faire plein de
> petits morceaux.

Ceci soulève tout de même un petit problème de conception de JOSM, ou
de l'API OSM, voire les deux.

En effet, la base de données OSM est d'abord à la base une base
purement relationnelle, mais dont une des tables, la table des nœuds,
contient un attribut de type coordonnées en 2D, cette table étant
indexée sur cet attribut avec un index spécial permettant de l'indexer
simultanément sur chaque coordonnée, et de façon à équilibrer dans
l'arbre de recherche le poids des éléments dans l'arbre.

Globalement un tel index "géométrique", quand il doit créer une
branche dans son arbre, car choisir de faire un découpage sur la
première ou la seconde coordonnée, avec une valeur intermédiaire
séparant chaque partie en deux groupes équilibrés en terme de nombre
d'objets, et en alternant si possible entre un découpage selon la
première ou la seconde coordonées ; l'index contient donc le numéro de
la coordonnée utilisée et les valeurs de seuil de découpage selon
cette coordonnée dans une page de données de taille maximale fixe,
contenant par ailleurs les références aux objets feuilles dans la
table relationnelle des nœuds).

Donc normalement le serveur de base de données est capable, grace à
cet index 2D, de non seulement trouver la liste de touts les points
dans un rectangle donné, mais aussi de répondre TRES EFFICACEMENT à
une requête similaire à :

  SELECT COUNT(*) FROM nodes
  WHERE (nodes.x, nodes.y) BETWEEN ($x0, $y0) AND ($x1, $y1)

-- Ne tenez pas compte de la syntaxe SQL réelle, cela dépend du moteur
SQL utilisé, la seule chose qui lui est demandée est de savoir gérer
un index multidimensionnel, au lieu des requêtes relationnelles basées
sur des valeurs simples telles que:

  SELECT COUNT(*) FROM nodes
  WHERE nodes.x >= $x0 AND  nodes.x <= x1
  AND nodes.y >= $y0 AND nodes.y <= $y1

où on ne dispose que d'un ou plusieurs index classiques privilégiant
un attribut unidemensionnel de coordonnée à un autre (par exemple x
puis y), ce qui n'est pas efficace du tout pour les requêtes
cartographiques (ou n'importe quel système contenant des données
multidimensionnelles, trop dépendantes de la projection utilisée et de
son orientation au départ totalement arbitraire mais très déterminante
avec des index simples).

On peut noter que les extensions "mutlidimentionnelles" des serveurs
relationnels ne se limitent pas aujourd'hui aux seules coordonnées
d'un système numérique homogène, mais peuvent s'utiliser même pour des
dimensions non numériques, l'index multidimensionnel étant optimisé de
façon à répartir les axes de découpage, là encore en sélectionnant
automatiquement (sur des critères de poids statistique) les valeurs
(non nécessairement numériques, du moment que leur type dispose d'un
ordre au moins partiel) de seuil sur chaque dimension. De même le
nombre de dimensions indexées ensembles n'est pas nécessairement
restreint à 2 ou 3.

Avec ce type de requête, le serveur n'aura pas à renvoyer au client
systématiquement la longue liste de noeuds contenus dans un rectangle
donné (donc pas non plus les chemins et relations qui référencent ces
points). Le serveur peut donc estimer correctement le volume d'une
telle liste, et répondre au client avec cette estimation, lui
demandant de subdiviser sa requête en autant de sous-rectangles que
nécessaires pour que le volume des noeuds de chaque sous-rectangle
reste sous une limite donnée.

De la même façon le serveur pourra aussi estimer correctement et assez
efficacement le nombre de chemins et de relations concernées. Le
serveur peut aussi indiquer au client les limites de volume qu'il
supporte.

Dès lors, la première chose effectuée par un client ne serait pas de
demander la liste des objets dans une zone, mais leur nombre !

Afin que le client s'adapte automatiquement à ce que le serveur
supporte, et que le client puisse informer l'utilisateur et lui
demander s'il souhaite poursuivre avant de procéder au redécoupage de
la zone demandée en autant de sous-rectangle que nécessaire.

De même le client pourra interrompre à tout moment (notamment s'il en
est averti par d'autres moyens) de ralentir le nombre de requêtes pour
ces sous-rectangles, voire aussi pour faire des requêtes plus
sélectives (en ajoutant un filtre sur le type d'objets demandés,
sachant que le logiciel client peut conserver la trace qu'un
sous-rectangle a pu être chargé complètement ou sélectivement avec un
filtre, ainsi que la trace datée de son dernier chargement, pour que
ce client puisse s'abstenir de faire certaines demandes de remises à
jour trop fréquentes, et inutiles si la requête n'a pas pour but de
modifier un objet dans la zone, puisque cette synchronisation plus
stricte peut se faire seulement au moment de créer ou modifier cet
objet dans une zone affichée beaucoup plus petite !).

On économiserait beaucoup de requêtes inutiles (et de bande passante)
au serveur avec une API pouvant répondre à ces requêtes de simples
comptage (au lieu de systématiquement des requêtes d'énumération
complète), et si JOSM savait alors les utiliser !




Plus d'informations sur la liste de diffusion Talk-fr