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

Répondre à