Requête PostGIS pour sélectionner des entités non connectées au reste du réseau routier?

8

J'ai un ensemble de données de routes dans une ville stocké dans une base de données compatible PostGIS. Je voudrais identifier et supprimer toute caractéristique qui n'est pas connectée au reste du réseau routier. Ce comportement est courant sur les bords des réseaux, où les données ont été écrêtées.

entrez la description de l'image ici

J'ai trouvé d'autres réponses sur le GIS SE qui font cela, mais elles semblent toutes utiliser ArcGIS, et je voudrais résoudre le problème en utilisant PostGIS, QGIS ou un script Python.

Mes ensembles de données peuvent inclure plus d'un million d'entités, donc les performances sont une préoccupation.

wmebane
la source

Réponses:

3

J'ai eu un problème similaire, j'ai donc développé un plugin QGIS qui est maintenant disponible dans le référentiel officiel des plugins QGIS et peut être trouvé dans le menu QGIS: Plugins / Gérer et installer des plugins ... et rechercher des îles déconnectées.

http://plugins.qgis.org/plugins/disconnected-islands/

Ce plugin s'exécute sur une couche polyligne, créant un graphe de réseau routier (ou ferroviaire, etc.) de liens connectés. Il analyse ensuite les sous-graphiques connectés, ceux qui sont connectés les uns aux autres, mais pas connectés à des liaisons isolées ou flottantes. Il crée un attribut supplémentaire contenant l'ID de groupe du sous-graphique. Cela peut ensuite être utilisé pour styliser le calque avec des styles classés, ou Zoomer sur la sélection. Les liens déconnectés peuvent ensuite être corrigés ou supprimés.

Le code source peut être dérivé de: https://github.com/AfriGIS-South-Africa/disconnected-islands

Mon ensemble de données compte environ 2 millions de liens et il a été analysé en moins de 15 minutes, en utilisant 55 Go de RAM.

Peter
la source
Cela semble parfait mais juste pour que vous sachiez quand je le télécharge, je reçois une erreur de plugin cassée :(
wmebane
Merci pour les commentaires @wmebane. J'aimerais résoudre le problème de plugin cassé pour vous. Veuillez signaler le message d'erreur à hub.qgis.org/projects/disconnected-islands/issues/new ou par e-mail (cliquez sur Auteur dans le gestionnaire de plugins).
Peter
8

Vous pouvez facilement utiliser PostGIS pour sélectionner des routes qui ne croisent aucune autre route:

SELECT id, geom FROM roads a
WHERE NOT EXISTS 
     (SELECT 1 FROM roads b 
      WHERE a.id != b.id
      AND   ST_Intersects(a.geom, b.geom))
dbaston
la source
4

Vous pouvez utiliser ce script QGIS Python pour détecter les lignes qui ne sont connectées à rien:

from qgis.utils import iface

layer = iface.mapCanvas().currentLayer() # Selected layer

featureList = list( layer.getFeatures() ) # Gets all features
allFeatures = { feature.id(): feature for feature in featureList }

# Spatial indexing
spatialIdx = QgsSpatialIndex()
map( spatialIdx.insertFeature, featureList )

resList = [] # ids of features not connected to anything

for f in featureList:

    # List of potentially connected features from spatial indexing
    ids = spatialIdx.intersects( f.geometry().boundingBox() )

    hasNeighbor = False

    for id in ids:
        ifeature = allFeatures[id]

        if ifeature.id() == f.id():
            continue

        # Checks if f is really intersecting with ifeature
        if f.geometry().intersects(ifeature.geometry()):
            hasNeighbor = True
            break # Exit current for loop

    if (not hasNeighbor) and (not f.id() in resList):
        resList.append( f.id() )

print resList

Notez que cela ne fonctionnera pas sur les lignes à plusieurs parties. Je ne pense pas que cela pourrait être fait beaucoup plus rapidement ...

ArMoraer
la source
J'ai le même problème que la question dans ce sujet. Merci pour votre solution, je l'ai appréciée. J'ai reçu l'erreur "'continuer' pas correctement en boucle". J'utilise qgis3.4 et python3.7, car je suis un débutant en python, j'espère que vous pourrez m'aider. Merci beaucoup ..
User0AB
3

Vous pouvez d'abord supprimer les routes faciles avec la méthode de @ dbaston, puis utiliser pgRouting pour trouver les cas les plus compliqués, comme lorsque vous avez un réseau de routes qui n'est pas connecté à un autre réseau.

Choisissez un segment de route qui fait définitivement partie du réseau principal, puis essayez de trouver un itinéraire de chaque autre segment à celui-ci. Si aucun itinéraire n'existe, supprimez le segment.

Rob Skelly
la source