Comment diviser les routes OSM en segments individuels aux intersections?

10

Je veux créer un réseau routier à utiliser avec pgRouting en utilisant les données OpenStreetMap. J'ai chargé un fichier de formes de GeoFabrik dans une table Postgres (avec PostGIS activé). Cependant, un problème que j'ai eu est que les routes ne s'arrêtent pas toujours aux intersections, j'ai donc décidé de les diviser toutes à chaque intersection ou passage.

Pour identifier toutes les intersections où les routes se croisaient ou se croisaient, j'ai utilisé ce qui suit SQL(semblable à une question précédente ):

CREATE TABLE split_points as
SELECT DISTINCT    
   ST_GeometryN(ST_Intersection(a.geom, b.geom),1) as geom      
FROM
   roads as a,
   roads as b
WHERE
    ST_Touches(a.geom, b.geom)
OR
    ST_Crosses(a.geom, b.geom)    
    AND a.gid != b.gid
GROUP BY
   ST_Intersection(a.geom, b.geom);

Je veux maintenant diviser les routes en utilisant ces points. J'ai utilisé l'approche suivante:

CREATE TABLE split_roads as
SELECT     
    ST_GeomFromEWKB((ST_Dump(ST_Split(g.geom, blade.geom))).geom) As geom,
    generate_series(1,ST_NumGeometries((ST_Split(g.geom, blade.geom)))) as gid
FROM    
    split_points as blade,
    roads as g
WHERE
    ST_Intersects(g.geom, blade.geom);

Le problème avec cette approche partagée est que la longueur totale de la route reste en plus de toutes les pièces séparées. Pour supprimer ces géométries de route non séparées qui ont été incluses, j'ai utilisé la ST_Equals()fonction pour les identifier et les supprimer:

DELETE FROM split_roads USING roads
WHERE ST_Equals(split_roads.geom, roads.geom)

Cependant, cette approche ne supprime pas toutes les géométries non divisées d'origine (bien qu'elle en supprime certaines). Existe-t-il une meilleure approche pour la suppression (ou globale) afin que je n'ai que les géométries divisées dans une table?

djq
la source
Selon la documentation, ST_Split ne renvoie pas la géométrie d'origine non fractionnée. Qu'est-ce que ce «.geom» supplémentaire à la dernière parenthèse fermante de la première ligne de votre instruction SELECT? Cela pourrait être aussi simple que de supprimer cela.
Scro
@Scro de quoi parlez .geom-vous? Je ne le vois pas!
djq
Je suppose que techniquement, ce serait la deuxième ligne de l'instruction SELECT. Je fais également référence à la création de la table "split_roads". C'est la ligne qui se termine par '))). Geom) as geom'.
Scro
hmm, je reçois une erreur quand je fais ça. ERROR: function st_geomfromewkb(geometry_dump) does not exist LINE 4: ST_GeomFromEWKB((ST_Dump(ST_Split(g.geom, blade.geom))))... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
djq
La ligne entière ressemblait-elle à ceci: ST_GeomFromEWKB ((ST_Dump (ST_Split (g.geom, blade.geom)))) As geom,
Scro

Réponses:

6

Pas une vraie solution à votre problème, mais essayez osm2po ... cela crée un code SQL parfait pour le routage en pgrouting: http://osm2po.de/

Étudiant SIG
la source
Merci pour la suggestion. J'ai essayé osm2pgroutingmais cela nécessite plus de mémoire que mon serveur et il se termine sans terminer.
djq
2
@djq osm2po peut gérer des fichiers beaucoup plus volumineux que osm2pgrouting. Il peut même charger planet.osm
underdark
ah, je pensais à l'origine que osm2poc'était une faute de frappe. Est-il facile de l'installer dans Ubuntu?
djq
C'est un fichier JAR compilé prêt (java). Il suffit de l'exécuter comme expliqué sur le site Web.
Étudiant SIG
11

Réponse simple: non. Vous ne devriez pas le faire de cette façon.

À partir des fichiers de formes de route OSM, il est impossible de faire la distinction entre les intersections et les passages supérieurs / inférieurs. Vous créerez des intersections qui n'existent pas dans la réalité si vous divisez toutes les routes qui semblent se croiser.

Vous devrez vous salir les mains avec le fichier OSM d'origine, si vous ne souhaitez pas utiliser les outils existants tels que osm2pgrouting (où le réseau est suffisamment petit) ou osm2po.

obscur
la source
1
Exactement . C'est aussi une autre erreur que certaines personnes commettent lorsqu'elles traitent des données navteq et teleatlas. Les passages inférieurs / supérieurs sont une douleur mais une réalité.
Ragi Yaser Burhum
1
Se mettre d'accord. Bienvenue dans SIG où les données sont toujours plus ou moins mauvaises
simplexio
3

À propos de votre problème général, en utilisant pgRouting: Je pense que @Uffer, @GisStudent et d'autres qui montrent comment utiliser "OSC & etc.", ils ont raison. Suivez les indices des "meilleures pratiques" et des "normes" ...

À propos de votre question: "diviser les routes en segments individuels aux intersections" ou "comment supprimer toutes les géométries non divisées d'origine". Je peux vous aider si vous montrez ici vos résultats ici, étape par étape ...

Première étape: l'analyse de la topologie

 CREATE TABLE split_points_topo as
  SELECT     
    a.gid as gid_a, b.gid  as gid_b, ST_Relation(a.geom, b.geom) as DE9IM_code
  FROM
    roads as a,
    roads as b
  WHERE a.gid != b.gid AND a.geom && b.geom;

 SELECT DISTINCT st_geometryType(geom) FROM roads;
 SELECT DISTINCT DE9IM_code FROM split_points_topo;
 -- list here the results o these two queries!  ... after we can continue.
Peter Krauss
la source
2

Une autre "solution pas vraiment à votre problème", mais notre convertisseur OSM se divise aux intersections pendant qu'il convertit d'OSM en SHP. Il est plus efficace de cette façon, car il peut comparer l'ID des nœuds, plutôt que de faire des calculs géométriques.

Uffe Kousgaard
la source
1

Une façon de le résoudre de manière algorithmique serait d'ajouter le point de départ et le point d'arrivée de chaque route entière à l'ensemble des «intersections», de sorte que vous puissiez être certain que chaque segment se trouve entre deux intersections.

relouer
la source