J'essaie d'utiliser QGIS 2.14 pour aligner un réseau routier sur une grille hexagonale, mais j'obtiens d'étranges artefacts.
J'ai créé une grille hexagonale avec MMQGIS , les cellules mesurent environ 20 x 23 m. J'ai tamponné le réseau routier de 1 m et je l'ai densifié pour qu'il y ait un nœud tous les quelques mètres. Vous pouvez voir ce que j'essaie de réaliser ci-dessous. Comme vous pouvez le voir, je peux le faire fonctionner dans certains cas: -
- le bleu est la route densifiée (une ligne tamponnée)
- le rouge est la version «hexifiée» - c'est ce que je veux trouver
- le gris est la grille hexagonale
J'ai ensuite utilisé la nouvelle fonction Snap geometries pour accrocher les nœuds au coin hexagonal le plus proche. Les résultats sont prometteurs, mais il semble y avoir des cas marginaux où la ligne se dilate pour remplir l'hexagone (ou une partie de celui-ci): -
La raison du tampon est que les géométries d'accrochage ne vous permettent pas de vous accrocher à une couche dont la géométrie est différente. Par exemple, vous ne pouvez pas accrocher des nœuds sur une couche LINE à des points sur une couche POINT). Il semble être le plus heureux de claquer POLYGON en POLYGON.
Je soupçonne que les routes se dilatent lorsqu'un côté de la ligne de route tamponnée saute d'un côté de la cellule hexadécimale et que l'autre côté saute de l'autre côté de la cellule hexadécimale. Dans mon exemple, les routes qui traversent l'ouest-est à un angle aigu semblent être les pires.
Des choses que j'ai essayées, sans succès: -
- tampon du réseau routier par une petite quantité, il reste donc un polygone mais est très mince.
- densifier les cellules hexagonales (donc il y a des nœuds le long des bords, pas seulement aux coins)
- faire varier la distance de capture maximale (cela a le plus grand effet, mais je n'arrive pas à trouver une valeur idéale)
- en utilisant des couches LINE, pas des POLYGONs
Je trouve que si je passe à l'utilisation de calques LINE uniquement, cela fonctionne pendant un certain temps, puis se bloque. Il semble enregistrer son travail au fur et à mesure - certaines lignes ont été partiellement traitées.
Quelqu'un connaît-il une autre façon d'aligner les points d'une ligne sur le point le plus proche d'une autre couche de ligne / polygone, idéalement sans avoir besoin d'utiliser postgres / postgis (bien qu'une solution avec postgis soit également la bienvenue)?
ÉDITER
Pour tous ceux qui souhaitent essayer, j'ai mis un projet QGIS de démarrage ici sur Dropbox . Cela inclut les couches Grille hexagonale et Lignes densifiées. (Le réseau routier provient d'OSM, il peut donc être téléchargé à l'aide de QuickOSM, par exemple si vous devez obtenir l'original pour densifier les routes).
Notez que c'est en OSGB (epsg: 27700) qui est une UTM localisée pour le Royaume-Uni, avec des unités en mètres.
Réponses:
Ma solution implique un script PyQGIS qui est plus rapide et plus efficace qu'un workflow impliquant un accrochage (je l'ai également essayé). En utilisant mon algorithme, j'ai obtenu ces résultats:
Vous pouvez exécuter les extraits de code suivants dans l'ordre à partir de QGIS (dans la console QGIS Python). À la fin, vous obtenez une couche mémoire avec les routes cassées chargées dans QGIS.
La seule condition préalable est de créer un Shapefile de route en plusieurs parties (utiliser
Processing->Singleparts to multipart
, j'ai utilisé le champfictitiuos
commeUnique ID field
paramètre). Cela nous donnera unroads_multipart.shp
fichier avec une seule fonctionnalité.Voici l'algorithme expliqué:
Obtenez les côtés hexagonaux les plus proches où les routes se croisent. Pour chaque hexagone, nous créons 6 triangles entre chaque paire de sommets voisins et le centroïde correspondant. Si une route croise un triangle, le segment partagé par l'hexagone et le triangle est ajouté à l'itinéraire final capturé. C'est la partie la plus lourde de tout l'algorithme, cela prend 35 secondes de course sur ma machine. Dans les deux premières lignes, il y a 2 chemins Shapefile, vous devez les ajuster pour qu'ils correspondent à vos propres chemins de fichier.
Débarrassez-vous des segments déconnectés (ou «ouverts») en utilisant des listes, des tuples et des dictionnaires Python . À ce stade, il reste des segments déconnectés, c'est-à-dire des segments qui ont un sommet déconnecté mais l'autre connecté à au moins 2 autres segments (voir les segments rouges sur la figure suivante). Nous devons nous en débarrasser.
Nous pouvons maintenant créer une couche vectorielle à partir de la liste des coordonnées et la charger sur la carte QGIS :
Une autre partie du résultat:
Si vous avez besoin d'attributs dans les itinéraires capturés, nous pourrions utiliser un index spatial pour évaluer rapidement les intersections (comme dans /gis//a/130440/4972 ), mais c'est une autre histoire.
J'espère que cela t'aides!
la source
Je l'ai fait dans ArcGIS, peut sûrement être implémenté en utilisant QGIS ou simplement python avec un package capable de lire les géométries. Assurez-vous que les routes représentent le réseau, c'est-à-dire qu'elles se croisent aux extrémités uniquement. Vous avez affaire à OSM, je suppose que c'est le cas.
Si vous ne voulez pas voir ceci:
N'essayez pas d'utiliser des points de chaînage sur les lignes Voronoi. J'ai peur que cela ne fasse qu'empirer les choses. Ainsi, votre seule option consiste à créer un réseau à partir des lignes de Voronoi et à trouver des itinéraires entre les points d'extrémité de la route, ce n'est pas très grave non plus
la source
Je sais que vous demandez une méthode QGIS, mais soyez indulgent avec moi pour une réponse arcpy:
Remarques:
la source
Si vous deviez diviser la ligne de route en segments où chaque segment était entièrement contenu par l'hexagone, votre décision sur les segments de ligne d'hexagone à utiliser serait de savoir si la distance entre le centre de gravité du segment de route divisé et le milieu de chaque côté de l'hexagone était inférieure à la moitié de la diamètre de l'hexagone (ou inférieur au rayon d'un cercle qui s'inscrit à l'intérieur de l'hexagone).
Ainsi, si vous deviez (un segment à la fois) sélectionner des segments de ligne hexagonale (où chaque segment est un côté de l'hexagone) qui sont à une distance du rayon de l'hexagone, vous pourriez copier ces géométries de ligne et les fusionner sur quel que soit l'identifiant unique que vous utilisez pour votre jeu de données routières.
Si vous avez des difficultés à fusionner sur l'identifiant unique, vous pouvez appliquer le tampon et sélectionner par emplacement uniquement sur ces segments pour appliquer les attributs de votre jeu de données de route; De cette façon, vous n'aurez pas à vous soucier de fausses correspondances avec un tampon trop volumineux.
Le problème avec l'outil d'accrochage est qu'il accroche des points sans discernement; il est difficile de trouver cette tolérance parfaite à utiliser. Avec cette méthodologie, vous identifieriez correctement les segments de ligne hexagonaux à utiliser, puis remplaceriez la géométrie de vos données de route (ou insérez les géométries dans un autre ensemble de données).
De plus, si le problème persiste avec les segments de ligne qui sautent d'un côté à l'autre de l'hexagone, vous pouvez diviser la ligne en segments par sommets, calculer la longueur de chaque ligne, puis supprimer tous les segments de ligne plus grands que la longueur moyenne d'un côté de l'hexagone.
la source
Le snapper de géométrie dans qgis 3.0 a été retravaillé et permet désormais d'aligner entre différents types de géométrie. Il a également beaucoup de correctifs. Vous pouvez essayer une version "instantané quotidien" pour accéder au snapper amélioré avant la sortie officielle de la version 3.0.
la source