en principe c'est toujours l'algo suivant à appliquer : - charger les membres des relations, ne garder que ceux de type "way" et ayant un rôle vide (déprécié), ou "outer"/"inner" (conserver ces rôles en métadonnées) - trouver les ways communs (avec le même id) : il ne devrait y avoir que 1 ou 2 avec le même iD s'il y en en 3 ou plus, la représentation est incorrecte - dans les paires de ways communs, ils ne devraient pas avoir le même rôle (ou bien les deux devraient avoir un rôle vide mais c'est une représentation dépréciée), avec un en "outer" l'autre en "inner", si c'est le cas, on supprime la paire. - avec le reste des ways restants, on charge la liste des noeuds pour chercher à les interconnecter : les interconnexions devraient être aux deux noeuds d'extrémité de chaque noeud, afin de former des "anneaux" (dans un premier temps garder les rôles des ways). Les interconnexions devraient se faire sur ces noeuds un nombre pair de ways - s'il y a un nombre impair de ways, la géométrie est incorrecte (non fermée) et il va falloir tenter de réparer en cherchant un way manquant entre deux noeuds d'extrémité de la liste qui sont les plus proches et pas déjà interconnectés par un way de la liste, afin d'ajouter ce way fictif manquant et compléter les anneaux pour former des interconnexions paires (attention on ne sait pas encore si c'est un way "inner" ou "outer", donc on ne peut que lui donner un rôle vide. - ensuite reste à savoir si les anneaux formée s'entrecroisent sur ces noeuds: si c'est le cas, il faut faire des échanges de listes de ways d'un anneau à l'autre. - à ce stade on peut vérifier les rôles inner/outer ou assigner ceux qui manquent. - enfin on s'intéresse aux autres noeuds (hors des extrémités) et à la géométrie exacte de chaque way pour voir s'il y a des intersections sur des noeuds intermédiaires entre deux ways, et on devra tenter de réparer là aussi (il faudra découper au besoin ces deux ways sur ces noeuds, au passage on peut se retrouver avec une intersection impaire après parcouru toute la liste, lors du découpage, on doit créer des ways plus courts dont on conserve en métadonnées les id's originels en métadonnées, mais come la phase précédente avait déjà rendu les anneaux fermés, la parité paire est garantie; au passage la détermination des rpoles "outer" et "inner" devra être revue dans une seconde passe sur les ways ainsi découpés dans la première passe). - on final on a une liste de ways fermés, les rôles sont tous corrects, on peut donc créer des multipolygones GIS fermés et correctement ordonnés (la seule chose à faire est de vérifier leur orientation, en sens antihoraire pour les "outer", et horaire pour les "inner". On a des métadonnées pour "logguer" les géométries incorrectes avec les id's des ways d'origine et donc aussi l'id des relations dont ils sont issus.
On n'est pas obligé de tenter les corrections (les rendus Mapnik d'OSM.org ne le font plus, il préfèrent maintenant produire un polygone manquant en ignorant les géométries incorrectes: cela accélère considérablement le rendu; ce type de traitement est plutôt fait maintenant par les outils de veille qualité, comme Osmose, qui journalisent ces éléments et créent des listes de signalements d'anomalies à corriger). Cela se passe lors de l'import des données OSM en PostGIS qui effectue une telle conversion de géométrie (mais ne fait plus de tentative de correction, qui est très lente et surcharge beaucoup le serveur d'import et ne permettrait pas au rendu de suivre assez vite le flux des modifications). On peut donc supposer que déjà dans PostGIS les géométries sont déjà toutes correctes. Mais faire cela dans une requête PostGIS est très compliquée ! Cela suppose aussi que de toute façon PostGIS a effectué les corrections nécessaires, mais on ne trouvera rien dans la base PostGIS si'il n'y a pas eu de correction car les polygones seront de toute façon manquants dans la base. PostGIS n'est pas vraiment fait pour ça, et c'est plutôt un traitement direct par un outil d'export et d'analyse des données OSM qui convient le mieux. Et là dans cet outil c'est bien plus simple car on s'intéresse juste à un jeu réduit de relations OSM et on peut même faire cet algo "à la main" ici. Ce n'est en effet pas bien compliqué de sortir la liste des ways membres (et leurs rôles à prendre en compte, pour éviter des membres qu'on trouve parfois (dont notamment des "admin_centre" qui ne sont pas des noeuds mais des ways de bâtiments, alors qu'on peut toujours positionner un noeud dans ce bâtiment, mais en général les "admin_centre", les noeuds membres, et les relations membres quelles qu'elles soient peuvent toujours être ignorés), et c'est facile de voir qu'il y a des paires de ways et les éliminer. L'outil "comcom" ne fait pas autre chose que de sortir des listes de ways membres à garder, et comme il ne reste alors que des ways isolés, leurs rôles "inner" ou "outer" (ou vide) dans les relations d'origine peut être gardé tel quel. On peut aussi le faire facilement dans JOSM en créant une relation temporaire et en y chargeant les way membres de chaque relation et supprimant les chemins communs (marqués en jaune lorsqu'on ajoute les membres de la relation suivante) et ce n'est pas difficile à faire. Et dans JOSM on peut ensuite exporter la relation temporaire (qu'on ne chargera pas vers OSM) sous forme de multipolygone GIS avec un greffon qui pourra générer un .kml ou un GeoJSON. Note: les relations peuvent sembler temporairement brisées dans la base OSM (à cause de modifications en cours sur des changesets pas encore fermés, cela arrive pendant quelques minutes voire quelques heures pendant une longue résolution de conflits entre plusieurs contriobuteurs, mais le plus souvent cela vient d'une utilisation incorrecte d'un éditeur comme JOSM ou d'un problème de connexion à la base de données avec iD, quand le serveur n'a pas répondu à temps à une requête de chargement des relations dépendantes et la requête a partiellement été abandonnée en cours). Mais cela vient aussi d'une mauvaise utilisation d'iD, ou quelqu'un a supprimé manuellement une référence d'un way à une relation parente en se trompant dans la sélection, ou avec un clic malencontreux (et iD ne permet pas de corriger facilement les grosses relations qu'il ne peut pas charger en totalité, mais seulement localement sur les zones où on a zoomé). Pour réparer les grosses relations comme les régions françaises, on n'y arrive pas dans iD (trop compliqué, d'autant plus qu'iD le fait en désordonnant les membres, ce qui ne facilite pas la réparation, mais ce qui est aussi un gros problèmes pour les relations "route" où l'ordre est significatif) mais seulement dans JOSM (et pour des grosses relations comme les régions françaises, il faut utiliser JOSM dans un JRE 64 bits avec plus de mémoire car la version 32 bits sature trop vite : il y a des centaines de milliers de noeuds et des dizaines de milliers de chemins si on charge des régions côtières aussi compliquées que la Bretagne, c'est moins critique pour les autres régions, mais aussi compliqué pour les frontières de la France entière, ou l'Espagne entière, ou le Golfe de Gascogne, ou la circonscriptions européenne Nord-Ouest en France). Le lun. 8 oct. 2018 à 22:11, Maël REBOUX <o...@breizhpositive.bzh> a écrit : > Je n’ai toujours pas trouver de solutions malgré différents essais. > J’aimerai éviter de créer une table en dur compliquée à maintenir à jour. > > > Le 28 sept. 2018 à 08:09, Maël REBOUX <o...@breizhpositive.bzh> a écrit : > > je vois l’idée mais c’est pas encore ça. > > … > "table": "( > SELECT DISTINCT way, COALESCE(tags -> 'name:br'::text) as name > FROM planet_osm_point > JOIN ( > WITH numbered AS( > SELECT row_number() OVER() AS row, entry > FROM( > SELECT unnest(members) AS entry > FROM planet_osm_rels > WHERE ARRAY['boundary','administrative']<@tags AND > ARRAY['admin_level','6']<@tags) AS mylist) > SELECT ltrim(a.entry,'n')::bigint AS osm_id > FROM numbered AS a JOIN numbered AS b > ON a.row = b.row-1 AND b.entry = 'admin_centre' > ) x > USING(osm_id) > ) AS data", > "geometry_table":"numbered", > "key_field": "", > "geometry_field": "way", > "asynchronous_request": "true", > "max_async_connection": "4", > "simplify_geometries": "true", > "extent_cache": "auto", > "extent": "-1363990,3994624,1824475,9411676" > }, > … > > donne une erreur différente : > > Postgis Plugin: ERROR: relation "numbered" does not exist > LINE 1: SELECT ST_SRID("way") AS srid FROM numbered WHERE "way" IS N... > ^ > in executeQuery Full sql was: 'SELECT ST_SRID("way") AS srid FROM numbered > WHERE "way" IS NOT NULL LIMIT 1;' > > logique : la géométrie n’est pas dans « numbered » (c’est pour récupérer > le admin_level dans la table des relations) > mais dans planet_osm_point > > donc on essaie : > > "table": "( > SELECT DISTINCT way, COALESCE(tags -> 'name:br'::text) as name > FROM planet_osm_point > JOIN ( > WITH numbered AS( > SELECT row_number() OVER() AS row, entry > FROM( > SELECT unnest(members) AS entry > FROM planet_osm_rels > WHERE ARRAY['boundary','administrative']<@tags AND > ARRAY['admin_level','8']<@tags) AS mylist) > SELECT ltrim(a.entry,'n')::bigint AS osm_id > FROM numbered AS a JOIN numbered AS b > ON a.row = b.row-1 AND b.entry = 'admin_centre' > ) x > USING(osm_id) > ) AS data", > "geometry_table":"*planet_osm_point*", > "key_field": "", > "geometry_field": "way", > "asynchronous_request": "true", > "max_async_connection": "4", > "simplify_geometries": "true", > "extent_cache": "auto", > "extent": "-1363990,3994624,1824475,9411676" > }, > > > et là ça passe : plus d’erreur MAIS je récupère pas de géométrie non plus > :( > > Le 27 sept. 2018 à 09:31, Christian Quest <cqu...@openstreetmap.fr> a > écrit : > > Les requêtes SQL sont ré-empaquetées par le driver postgis de mapnik et là > je pense qu'il ne sait pas détecter que c'est dans "data" qu'il va trouver > "way". > > Essaye en ajoutant un paramètre "geometry_table": "data" voire aussi > "geometry_field": "way" > > Pour l'ensemble des paramètres qu'on peut passer, voir: > https://github.com/mapnik/mapnik/wiki/PostGIS > > Je pense aussi qu'un && !bbox! quelque part sera peut être nécessaire pour > être sûr que la requête soit limitée à l'emprise à rendre... > > > Le jeu. 27 sept. 2018 à 07:45, Maël REBOUX <o...@breizhpositive.bzh> a > écrit : > >> J’ai oublié de mettre la déclaration de la couche dans le projet : >> >> >> { >> "id": "places_admin_6", >> "name": "places_admin_6", >> "class": "", >> "Datasource": { >> "type": "postgis", >> "host": "db.openstreetmap.local", >> "user": "osm", >> "password": "osm", >> "dbname": "osm", >> "table": "( >> SELECT DISTINCT way, COALESCE(tags -> 'name:br'::text) as name >> FROM planet_osm_point >> JOIN ( >> WITH c AS( >> SELECT row_number() OVER() AS row, entry >> FROM( >> SELECT unnest(members) AS entry >> FROM planet_osm_rels >> WHERE ARRAY['boundary','administrative']<@tags AND >> ARRAY['admin_level','6']<@tags) AS mylist) >> SELECT ltrim(a.entry,'n')::bigint AS osm_id >> FROM c AS a JOIN c AS b >> ON a.row = b.row-1 AND b.entry = 'admin_centre' >> ) x >> USING(osm_id) >> ) AS data", >> "key_field": "", >> "geometry_field": "way", >> "asynchronous_request": "true", >> "max_async_connection": "4", >> "simplify_geometries": "true", >> "extent_cache": "auto", >> "extent": "-1363990,3994624,1824475,9411676" >> }, >> "geometry": "point", >> "srs-name": "3857", >> "srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 >> +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over", >> "extent": [ -10, 34, 20, 70 ], >> "advanced": {} >> } >> >> >> >> Le 27 sept. 2018 à 00:10, Maël REBOUX <o...@breizhpositive.bzh> a écrit : >> >> Bonjour tous, >> >> Je cherche à faire apparaître sur une carte en ligne les préfectures et >> leur nom en breton. >> >> La façon d’y arriver est « connue » : il faut faire une jointure entre la >> table planet_osm_point (qui contient le point et le nom) et la >> table planet_osm_rels (qui elle contient l’info admin_level). >> >> Cela donne une requête qui s’exécute très bien en temps normal (pgAdmin >> ou dans une vue ou une requête d’insertion de données / create table) : >> >> SELECT DISTINCT way, COALESCE(tags -> 'name:br'::text) as name >> FROM planet_osm_point >> JOIN ( >> WITH numbered AS( >> SELECT row_number() OVER() AS row, entry >> FROM( >> SELECT unnest(members) AS entry >> FROM planet_osm_rels >> WHERE ARRAY['boundary','administrative']<@tags AND >> ARRAY['admin_level','6']<@tags) AS mylist) >> SELECT ltrim(a.entry,'n')::bigint AS osm_id >> FROM numbered AS a JOIN numbered AS b >> ON a.row = b.row-1 AND b.entry = 'admin_centre' >> ) x >> USING(osm_id); >> >> >> source : >> https://dba.stackexchange.com/questions/104943/osm2pgsql-select-relation-member-by-role >> >> >> Mais si je mets cette requête dans une déclaration de couche pour un >> projet mml servi par kosmtik j’obtiens une erreur dans kosmtik : >> >> Postgis Plugin: ERROR: relation "numbered" does not exist LINE 1: SELECT >> ST_SRID("way") AS srid FROM numbered WHERE "way" IS N... ^ in executeQuery >> Full sql was: 'SELECT ST_SRID("way") AS srid FROM numbered WHERE "way" IS >> NOT NULL LIMIT 1;' encountered during parsing of layer 'places_admin_6' in >> Layer >> >> >> En loggant l’erreur dans PostgreSQL : >> >> 2018-09-26 23:24:56.797 CEST [32589] STATEMENT: SELECT ST_SRID("way") AS >> srid FROM numbered WHERE "way" IS NOT NULL LIMIT 1; >> 2018-09-26 23:24:56.798 CEST [32590] LOG: statement: SELECT >> ST_SRID("way") AS srid FROM numbered WHERE "way" IS NOT NULL LIMIT 1; >> 2018-09-26 23:24:56.798 CEST [32590] ERROR: relation "numbered" does not >> exist at character 36 >> >> >> Je n’arrive pas à cerner le problème. Bien sûr si on change le nom >> « numbered » par autre chose, le message d’erreur fera référence à ce >> nouveau nom. >> J’ai pas testé directement sur un serveur de tuiles mais je vois pas >> pourquoi ça passerait. >> Si quelqu’un a une piste… >> >> Cdt, Maël evit osm-bzh >> >> >> >> >> >> >> >> >> >> >> >> >> _______________________________________________ >> Talk-fr mailing list >> Talk-fr@openstreetmap.org >> https://lists.openstreetmap.org/listinfo/talk-fr >> >> >> _______________________________________________ >> Talk-fr mailing list >> Talk-fr@openstreetmap.org >> https://lists.openstreetmap.org/listinfo/talk-fr >> > > > -- > Christian Quest - OpenStreetMap France > _______________________________________________ > Talk-fr mailing list > Talk-fr@openstreetmap.org > https://lists.openstreetmap.org/listinfo/talk-fr > > > _______________________________________________ > Talk-fr mailing list > Talk-fr@openstreetmap.org > https://lists.openstreetmap.org/listinfo/talk-fr > > > _______________________________________________ > Talk-fr mailing list > Talk-fr@openstreetmap.org > https://lists.openstreetmap.org/listinfo/talk-fr >
_______________________________________________ Talk-fr mailing list Talk-fr@openstreetmap.org https://lists.openstreetmap.org/listinfo/talk-fr