Suite

Jointure spatiale avec d'énormes ensembles de données


Comment faire une jointure spatiale avec ArcGIS avec ces énormes jeux de données ?

  • Cible: près de 3 millions de carrés taille 500x500m (la table attributaire est pratiquement vide)
  • Rejoindre la fonctionnalité: 12000 polylignes
  • Opération: un à plusieurs
  • Correspondre: se croisent

Toutes mes tentatives ont échoué :

  • À partir de l'outil Jointure spatiale dans la boîte à outils: après 15 min, la sortie est un fichier où aucune jointure n'a été effectuée (le champ Join_Count est égal à 0 dans toutes les lignes)
  • Depuis la boîte de dialogue: Cela semble fonctionner mais mon estimation est qu'il faut 4 jours pour terminer - sans aucune garantie que la sortie sera correcte.

Cela fonctionne lorsque je fais une jointure spatiale d'une petite zone.

Des idées sur la façon de le faire de manière appropriée?

J'utilise la géodatabase fichier, ArcGIS 10.2, traitement en arrière-plan, 32 Go de RAM

(L'idée est de superposer ces polylignes à la grille (les carrés de 500x500m). Je ferai ensuite un fondu pour savoir combien de lignes il y a dans chaque carré. Enfin, je ferai une carte de densité.)


Je viens de prendre un sous-ensemble des principales autoroutes américaines "Data & Maps" d'Esri (CONUS avec CLASS=1 - 11 803 caractéristiques), je l'ai projeté sur PCS_NAD_1983_CONUS_ALBERS et j'ai généré une grille polygonale de 2 km x 2 km dans l'enveloppe {-2,6 m, 0,2 m, +2,4 m, 3,2 m} (2 500 x 1 500 cellules = 3,75 m de polygones) pour simuler vos données.

Ensuite, j'ai utilisé Kernel Density pour créer une carte thermique de cellules de 2 km x 2 km (en 0,1 minute):

Ensuite, j'ai croisé les lignes à travers les polygones (10,8 minutes pour générer 75 221 lignes discrètes) et j'ai exécuté Frequency pour générer un nombre d'identifiants de polygones (0,2 minute pour identifier 55701 grilles croisées). À partir de là, il était plus facile de remplir la classe d'entités source « icount » avec un script python (qui a duré 19,7 minutes) :

import arcpy arcpy.env.workspace = r'D:Tempgis_seoverlay.gdb' tablePath = 'grid_fréquence_tab' layerPath = 'grid_albers' tableCols = ["FID_grid_albers","fréquence"] count = 0 avec arcpy.da. SearchCursor(tablePath, tableCols) as cursor1 : pour row1 in cursor1 : count = count + 1 whereClause = """{0} = {1}""".format("Objectid_1",str(row1[0])) avec arcpy.da.UpdateCursor(layerPath, "icount", whereClause) as cursor2 : pour row2 in cursor2 : row2[0] = row1[1] cursor2.updateRow(row2) print str(count)+" features updated"

Ensuite, j'ai utilisé une définition de requête pour sélectionner uniquement les polygones avec un nombre supérieur à zéro, et j'ai copié le résultat dans une nouvelle classe d'entités surfaciques (0,2 min) :

Je vous recommande d'inclure une distance tampon dans votre méthode de recherche (la densité de noyau facilite cette opération), car le grand nombre de cellules de la grille rend difficile la recherche de grandes quantités de chevauchement :

Il existe de nombreuses autres variantes possibles, notamment l'utilisation de la classe d'entités in_memory pour améliorer les performances des requêtes et l'utilisation de deux curseurs de recherche DA avec un dictionnaire pour compiler une table polygon-id/count en mémoire (puis mettre à jour les polygones avec un curseur DA), mais le processus ne doit pas prendre des jours si vous utilisez la bonne approche.


C'est une autre façon de résoudre ce problème, avec un script Python qui coupe les lignes pour chaque polygone (itération sur tous les polygones), compte les lignes restantes et écrit dans la table attributaire.

Ce qui est présenté ici, ce sont des morceaux de code que j'avais qui traînaient et qui n'est pas correctement testé ni un script complet. Il est configuré comme un outil de script dans Arcmap. J'ai dû changer quelques noms de variables, j'en ai peut-être manqué un ou deux.

# Lecture des entrées des polygones utilisateur = arcpy.GetParameterAsText(0) lines = arcpy.GetParameterAsText(1) outcm = arcpy.GetParameterAsText(2) # Créer des FC temporaires tempLines = arcpy.CreateFeatureclass_management('in_memory', 'tempLines', "POLYLINE" , lines) mem_polygons = "in_memorymem_polygons" arcpy.CopyFeatures_management(polygons, mem_polygons) #Clip le fichier d'entrée pour chaque 50 000 polygones, et traite une pièce à la fois cursorFields = ('[email protected]', 'LineCount',… ) # Quels que soient les champs dont vous avez besoin avec arcpy.da.UpdateCursor(mem_polygons, cursorFields) comme cmrows : pour la ligne dans les cmrows : arcpy.env.overwriteOutput = True arcpy.Clip_analysis(lines, row[0], tempLines) arcpy.env.overwriteOutput = False ## Effectuez les calculs dont vous avez besoin, par ex. compter les lignes dans tempLines… ## Écrire dans la ligne du champ LineCount[1] = #votre variable de comptage cmrows.updateRow(row) arcpy.CopyFeatures_management(mem_polygons, outcm)

En option, vous pouvez créer des fichiers de sortie tous les quelques dizaines de milliers de polygones, juste pour être sûr. Cela permettrait également un traitement par lots plus facilement. Avec 32 Go de RAM, vous devriez pouvoir traiter pas mal de polygones avec l'espace in_memory. Cependant, vous pouvez également l'écrire dans un fichier de formes ou un gdb normal si cela devient un problème de mémoire.


Semblable à @Vince et @Martin, si vous vouliez voir combien de lignes croisaient chaque cellule de polygone, vous pourriez :

  1. Utilisez Feature to Line pour couper les lignes par la limite du polygone, puis supprimez les lignes qui appartenaient réellement au polygone (puisqu'elles sont toutes les deux présentes dans la sortie) de sorte que vous n'ayez que des lignes appartenant à la polyligne FC.
  2. Utilisez Tabulate Intersection avec le compter option pour résumer le nombre de lignes "coupées" tombées à l'intérieur de chaque cellule de polygone.


Voir la vidéo: Lähdekritiikki - Äidinkieli, Kirjoittaminen ja Kirjallisuus ÄKK (Octobre 2021).