Suite

La dissolution des polygones échoue sur les ordinateurs avec une petite quantité de RAM

La dissolution des polygones échoue sur les ordinateurs avec une petite quantité de RAM


Lorsque j'essaie de dissoudre un polygone via un script arcpy, l'opération échoue avec l'erreur 999999 sur les ordinateurs avec une petite quantité de RAM [~3 Go] (problème connu).

Malheureusement ni l'un ni l'autre :

  • arcpy.Dissolve échoue ; besoin d'une solution de contournement arcpy pour contourner plusieurs parties
  • Pourquoi l'outil de dissolution ne fonctionne-t-il pas ? ni
  • Dissoudre ne fonctionne pas dans ArcGIS 10 fonctionne pour moi, donc je pensais d'abord diviser le polygone en plus petits morceaux, les traiter puis les fusionner? Mais je n'ai absolument aucune idée de comment faire. Des idées? Peut-être y a-t-il une autre approche qui ne m'est pas venue à l'esprit?

Un exemple de polygone à tester peut être trouvé ici, je suis en train de dissoudre sur le champ "Godziny" avec les paramètres par défaut :

arcpy.Dissolve_management(path_to_original_shp, path_to_dissolved_shp, "Godziny")

AJOUTÉE: Malheureusement, lorsque j'ai testé la solution de Geog et que cela a fonctionné, ce n'était qu'un coup de chance. Pourtant, 99 dissolutions sur 100 échouent. Cependant, les conditions d'échec sont assez étranges. Si je lance la dissolution en tant qu'outil dans ArcMap, il se dissout très bien (en 30 secondes environ). Si je l'exécute à partir de l'interpréteur de python (peu importe que ce soit dans ArcMap ou non), il se dissout également correctement. Cependant, si je l'exécute à partir de mon script comme l'une des fonctions d'une chaîne de traitement, il échoue (il est bloqué pendant environ 20 à 30 minutes, l'utilisation de la mémoire augmentant lentement mais constamment au fil du temps, puis génère une erreur 999999 - "Topologie invalide").

La façon dont j'exécute ce script est un peu inhabituelle, car j'ai une interface graphique construite avec wxpython que j'exécute dans ArcMap, à partir de laquelle la chaîne de traitement avec dissolution est exécutée. Je l'exécute sur une machine Windows XP SP3 avec 3 Go de RAM. Si j'utilise une machine avec plus de RAM et Windows 7 ou 8 (64 bits mais sans géotraitement en arrière-plan 64 bits), tout fonctionne très bien. En plus de cela, si je commente la dissolution et le reste de la chaîne, exécutez-la, puis commentez la première partie et exécutez-la à partir du point de dissolution, cela fonctionne également très bien. Cela m'a donné l'idée que je pourrais verrouiller les ressources d'une manière ou d'une autre, j'ai donc essayé de faire gc.collect(), mais sans succès.

Je viens d'essayer d'exécuter le script à partir de la ligne de commande et cela fonctionne également bien… Donc, je suppose qu'il y a quelque chose qui ne va pas lors de la dissolution à partir de mon interface graphique d'extension, mais je n'ai aucune idée de la façon dont mon extension pourrait influencer la fonction car je ne modifie pas le environnement de quelque manière que ce soit.

La chaîne de traitement que je fais ressemble à ceci :

arcpy.CheckOutExtension("spatial") # obtenir les licences nécessaires ccm1_cut = ExtractByMask(project_manager.conf_dict["CCM1"], project_manager.conf_dict["hordist"]) ccm2_cut = ExtractByMask(project_manager.conf_dict["CCM2"], project_manager.conf_dict ["hordist"]) ccm3_cut = ExtractByMask(project_manager.conf_dict["CCM3"], project_manager.conf_dict["hordist"]) ccm4_cut = ExtractByMask(project_manager.conf_dict["CCM4"], project_manager.conf_dict["hordist"]) ccm5_cut = ExtractByMask(project_manager.conf_dict["CCM5"], project_manager.conf_dict["hordist"]) # fusion des calques ccm ccm_merged = Con(IsNull(ccm1_cut), Con(IsNull(ccm2_cut), Con(IsNull),(ccm3_cut), (IsNull(ccm4_cut), Con(IsNull(ccm5_cut), project_manager.conf_dict["lu_speed"], ccm5_cut), ccm4_cut), ccm3_cut), ccm2_cut), ccm1_cut) walk_speed_cut = ExtractByMask(project_manager.conf_dict,["walkmanager .conf_dict["hordist"]) travel_speed_raster = walk_speed_cut / ((Float(ccm_merged)) / 100) travel_speed_raster.save(travel_s peed) # création de la distance du chemin ipp = project_manager.get_ipp_path() path_dist_raster = PathDistance(ipp, travel_speed) # normalisation aux heures path_dist_norm_raster = Divide(path_dist_raster, 3600) path_dist_norm_raster.save(travel_time_normalised) # création de classes d'heures remapRange() remapRange() ) temp_reclass = Reclassify(travel_time_normalised, "VALUE", remap_range, "NODATA") temp_reclass.save(travel_time_classes) # conversion du temps de trajet raster en polygones arcpy.RasterToPolygon_conversion(travel_time_classes, travel_time_classes_shp, "SIMPLIFY"), "SIMPLIFY" arcpy.AddField_management(travel_time_classes_shp, "Godziny", "SHORT") arcpy.CalculateField_management(travel_time_classes_shp, "Godziny", "[GRIDCODE]", "VB") # dissolution de polygones arcpy.Dissolve_management,class_hp, "Godziny", "[GRIDCODE]", "VB")

L'outil Dissolve peut créer un Godzilla en combinant des fonctionnalités plus petites (mais toujours assez grandes) en une seule fonctionnalité. C'est ce qu'on appelle le problème combinatoire. L'outil Dissolve a une logique qui l'empêche de créer un Godzilla (vous recevrez le code d'avertissement 000059) mais cette logique est basée sur la mémoire disponible de la machine au moment où Dissolve est exécuté. Ainsi, bien que la sortie puisse ne pas être un Godzilla sur la machine sur laquelle Dissolve s'est exécuté, elle peut être sur une autre machine avec moins de mémoire disponible. en savoir plus sur Dicing Godzillas (L'outil Dice prend des entités en entrée et une limite de sommet et génère une nouvelle classe d'entités avec des entités découpées en dés, comme illustré ci-dessous. L'outil Dice fonctionne avec des multipoints, des lignes et des polygones.)


Je créerais un polygone à 4 régions et «découperais» chacune des quatre parties dans des fichiers de formes distincts, puis exécuterais la «dissolution». Ensuite, "fusionnez-les" ensemble et vous devrez probablement exécuter une dernière "dissolution".

Je créerais les 4 polygones via l'outil de résille en fonction de l'enveloppe de l'ensemble de polygones d'entrée.

voici un lien. http://forums.arcgis.com/threads/40500-Split-polygon


ArcGIS Desktop 10.2 semble avoir des problèmes de gestion de la mémoire de géotraitement. Exécution répétée d'opérations de géotraitement dans un seul processus Python volonté éventuellement planter avec la fausse erreur « Topologie invalide ». Le temps que cela prend dépend des ressources système et de la complexité des opérations en cours d'exécution.

Une solution qui fonctionne, à partir de là, consiste à exécuter les opérations de géotraitement en tant que leur propre processus. Cet exemple est pour le fondu enchaîné, mais l'effacement et le découpage peuvent être effectués de la même manière.

import subprocess def call_dissolve_in_separate_process(input_fc, new_fc_loc): args = (input_fc, new_fc_loc) cmd = r"C:Python27ArcGIS10.2python.exe C:projectsmy_projectstandalone_dissolve.py " + " ". args) chld = subprocess.Popen(cmd, stdout=subprocess.PIPE) r = chld.communicate() if chld.returncode != 0: print str(chld.returncode) # Ici, vous pouvez générer une sorte d'erreur, ou récursivement réessayer. else : imprimer '
La dissolution et l'enregistrement ont pris
%s secondes
' % (time.time()-start_time) return new_fc_loc

Dans un module séparé appelé standalone_dissolve.py

"""Dissoudre dans un sous-processus séparé.""" import sys from arcpy import Dissolve_management args = sys.argv script, input_fc, new_fc_loc = args def main(input_fc, new_fc_loc): try: print 'Essayer de dissoudre' Dissolve_management(input_fc, new_fc_loc) ) print 'Dissoudre travaillé' return 0 except Exception as ex: print ex.message print 'Dissolve failed, try again!' # Il y a d'autres choses qui ne vont pas avec le géotraitement, cette approche récursive vient du "si au début vous ne réussissez pas, réessayez jusqu'à ce que l'école réussie de la pensée arcpy scripting". Vos besoins peuvent différer. main(input_fc, new_fc_loc) return 1 # Quelqu'un suggère une manière plus élégante main(input_fc, new_fc_loc)

C'est compliqué, mais vous obtenez un nettoyage complet des ressources après la fin de chaque opération de géotraitement.


Parfois, il est utile de travailler avec un calque plutôt que directement sur les données. Vous devriez essayer de créer un tel calque avant d'exécuter les outils (avec arcpy.MakeFeatureLayer_management), puis vous supprimez ce calque (avec arcpy.Delete_management, en supprimant le calque, pas la classe d'entités, bien sûr)

Cela peut également aider à éviter les entités multiparties à l'aide de l'option "SINGLE_PART" et à réduire le nombre de sommets à l'aide de "simplify (vous avez simplifié au stade de la conversion raster en polygone.

Enfin, il existe une solution de contournement à dissoudre si vous avez la licence avancée, mais cela prend du temps. Utilisez polygone à ligne avec l'option d'identifier les polygones gauche et droit, joignez les champs d'origine dont vous avez besoin pour la dissolution, sélectionnez toutes les lignes qui ont une valeur différente à gauche et à droite, puis convertissez ces lignes en polygones : vous avez dissous votre jeu de données .


J'ai eu ce problème.

Voici ce que fait arcmap en arrière-plan et vous devriez faire de même.

  1. 10000 tranches d'entités : sélectionnez les 10 000 principales entités, créez un calque, dissolvez
  2. Nettoyage : toujours, mais toujours utiliser des "noms générés par arcpy" (il existe une fonction, ne vous en souvenez pas), ne réutilisez pas les noms (couches ou quoi que ce soit) et supprimez les couches inutilisées/réutilisées à la fin de chaque cycle d'itération .
  3. Modifiez l'espace de travail et le gdb de travail par défaut.

" J'ai une interface graphique construite avec wxpython " -> se débarrasser de l'interface graphique dans wx. Il y a des problèmes connus pour cette combinaison. Le module arcpy utilise des objets COM/OLE quelque part. " A partir de la version 0.5 Wx::ActiveX est compatible avec les objets Win32::OLE " -> utilisez-vous la version 64 bits ? Utilisez-vous Arcgis 10.1 ?!

Acclamations! J'espère que cela vous aidera à comprendre le problème principal.


Je suppose qu'il s'agit d'un problème de récupération de place - l'une des classes ne sort pas assez longtemps de la portée pour que la collecte se produise avant qu'elle ne soit réinitialisée. Les frameworks managés n'y parviennent pas toujours lorsque leurs ressources sont utilisées au maximum et le fait que cela ne se produise que pendant la version du script, puis de manière quelque peu aléatoire (ce qui peut être dû à d'autres opérations système) me suggère cette cause.

Quant aux solutions, il est difficile de changer si le code concerné est enveloppé dans une classe propriétaire. Si vous pouvez forcer GC d'une manière ou d'une autre (tout mettre dans une autre classe peut-être et mettre cela hors de portée ?), cela pourrait fonctionner.

Ou peut-être créer des rasters pour les paramètres de la classe calculatefield_management et utiliser un calc raster à la place, puis convertir en polys à la fin, évitant ainsi de dissoudre tous ensemble ?


Voir la vidéo: Augmenter les performances Windows 7 - 8 -