Suite

Mettre à jour les valeurs de la couche une à la couche deux où il n'y a pas d'ID identique mais une géométrie identique


J'ai un énorme problème et c'est d'obtenir la valeur d'une couche dans une autre. C'est un réseau avec plus d'un million de liens et j'ai besoin de mettre à jour une table à partir d'une couche de + 100 000 liens. J'utilise QGIS et j'ai essayé de se croiser, de se chevaucher sur des données plus petites mais je n'obtiens pas le résultat souhaité. Les deux couches ont une géométrie identique mais une couche par exemple peut avoir un lien long par rapport à la couche deux qui peut avoir plusieurs liens (intersections de routes) donc le chevauchement et l'intersection ne fonctionnent pas. J'ai essayé les options "Sélectionner par emplacement" et "Inclure complètement les fonctionnalités d'entrée dans les fonctionnalités de sélection". si cela fonctionne ou simplement gelé dans le processus. Tout ce que je veux, c'est faire correspondre les données et mettre à jour les valeurs d'une couche à l'autre. Comme il n'y a pas d'ID identique, je ne peux pas utiliser la fonction "Rejoindre", mais je dois utiliser la correspondance de géométrie à la place. Existe-t-il un autre moyen de contourner ce problème ?


Avec 6 couches, le code Python exécuté dans les attributs de la console Python (ou exécuté depuis l'éditeur) sera transféré aux entités de la couche 1. La couche 1 contient les entités qui fournissent la géométrie principale. Ils doivent être égaux, contenus par ou disjoints des géométries des entités des autres couches.

Couche 1 (différenciation des routes par nombre de voies ; attribut : Voies; identifié par l'identifiant de la fonctionnalité) ; dans cet exemple le géométrie principale

Couche 2 ( (différenciation par nom de rue ; attribut : nom de rue)

Etc.

Maintenant le code Python :

de PyQt4.QtCore import QVariant import datetime print 'À partir de : ', datetime.datetime.now() # obtenir des calques; une ligne pour chaque couche à évaluer, avec layer1 contenant la géométrie principale layer1 = QgsMapLayerRegistry.instance().mapLayersByName('thtn-vbg')[0] layer2 = QgsMapLayerRegistry.instance().mapLayersByName('thtn-vbg_funk')[ 0] layer3 = QgsMapLayerRegistry.instance().mapLayersByName('thtn-vbg_speed')[0] layer4 = QgsMapLayerRegistry.instance().mapLayersByName('thtn-vbg_street_name')[0] layer5 = QgsMapLayerRegistry.instance().mapLayersByName('thtn-vbg_street_name')[0] layer5 = QgsMapLayerRegistry(). 'thtn-vbg_one_way')[0] layer6 = QgsMapLayerRegistry.instance().mapLayersByName('thtn-vbg_urban')[0] # spécifiez pour chaque couche l'attribut à transférer à la géométrie maître attribute_dict = {layer2 : 'KLASS', layer3: 'HTHAST', layer4: 'NAMN', layer5: 'RIKTNING', layer6: 'RLID'} # divise les lignes en segments et enregistre tous les segments dans un dict avec les attributs fournis # master geometry; doit être égal à, contenu par ou disjoint des autres géométries segments = {} pour la ligne dans layer1.getFeatures() : c = 1 pour i dans range(len(line.geometry().asPolyline())-1) : segments[((line.geometry().asPolyline()[i][0], line.geometry().asPolyline()[i][1]), (line.geometry().asPolyline()[i+ 1][0], line.geometry().asPolyline()[i+1][1]))] = {'fid': line.id(), 'seq': c} c += 1 # autre géométries avec attributs pour the_layer, the_attrib dans attributs_dict.items() : pour la ligne dans the_layer.getFeatures() : pour i dans range(len(line.geometry().asPolyline())-1 : key = ((line. geometry().asPolyline()[i][0], line.geometry().asPolyline()[i][1]), (line.geometry().asPolyline()[i+1][0], line.geometry().asPolyline()[i+1][1])) si la clé dans les segments : segments[key][the_attrib] = line.attribute(the_attrib) print 'Segments construits : ', datetime.datetime.now () # préparer les segments à dissoudre composé = {} pour le segment en segments : fid = segments[segment].get('fid', None) if fid : si fid pas dans compose : compose[fid] = { } _attributes = [segments[segment]['fid']] _attributes.extend([segments[segment].get(the_attrib, None) pour le_couche, the_attrib dans attributs_dict.items()]) composé[fid]['attributes' ] = _attributes compos[fid]['vertices'] = [(segments[segment]['seq'], (segment[0][0], segment[0][1]), (segment[1][0 ], segment[1][1]))] else : composé[fid]['vertices'].append((segments[segment]['seq'], (segment[0][0], segment[0] [1]), (segment[1][0], segment[1][1]))) print 'Segments ordonnés : ', datetime.datetime.now() # définir la couche QGIS avec les attributs layer = QgsVectorLayer('LineString ?crs=EPSG:3006', 'Résultat', 'mémoire') prov = layer.dataProvider() attributs = [QgsField('fid', QVariant.Int)] attributs.extend([QgsField(the_attrib, QVariant.String) pour the_layer, the_attrib dans attributs_dict.items()]) attributs.append(QgsField('length', QVariant.Double)) prov.addAttributes(attributes) QgsMapLayerRegistry.instance().addMapLayer(layer) # créer des fonctionnalités feats = [] layer.startEditing() pour composer dans com posé : composé[composer]['sommets'].sort() feat = QgsFeature() sommets = [QgsPoint(composé[composer]['sommets'][0][1][0], composé[composer][' sommets'][0][1][1]), QgsPoint(composé[composer]['sommets'][0][2][0], composé[composer]['sommets'][0][2] [1])] pour idx dans range(1, len(composed[compose]['vertices'])): vertices.append(QgsPoint(composed[compose]['vertices'][idx][2][0] , compos[compose]['vertices'][idx][2][1])) feat.setGeometry(QgsGeometry.fromPolyline(vertices)) compos[compose]['attributes'].append(feat.geometry(). length()) feat.setAttributes(composed[compose]['attributes'] ) feats.append(feat) print 'Lignes construites : ', datetime.datetime.now() # enfin ajouter toutes les fonctionnalités créées et enregistrer les modifications prov.addFeatures (feats) layer.updateExtents() layer.commitChanges() print 'Terminé :', datetime.datetime.now()

Le résultat est écrit sur une couche mémoire, que vous pouvez enregistrer sur le disque. Et voici le résultat final :

Routes symbolisées par le nombre de voies et étiquetées avec le nom de la rue.

Le script a été testé avec 16 000 entités principales, qui reçoivent les attributs de 30 000 entités dans 5 couches. Le temps d'exécution était de 1 minute sur un PC de 3 ans avec QGIS 2.8.2