Wie klassifiziere ich einen sehr großen Landbedeckungsdatensatz neu?

10

Betrachten Sie den NLCD2001 Land Cover-Datensatz für Alaska ( Download-Link ). Ich muss diesen Datensatz neu klassifizieren, damit nur Pixel mit den Werten 41, 42 und 43 erhalten bleiben. Alle anderen Pixelwerte sollten NoData werden (oder 0, falls erforderlich).

Dies scheint eine einfache Aufgabe zu sein, für die nur ein Aufruf des Reclassify-Tools erforderlich ist. Leider führt jeder Anruf zu einer vagen und nicht hilfreichen Fehlermeldung:

Executing: Reclassify "D:\ak_nlcd_2001_land_cover_3-13-08_se5.img" Value "0 40 0;41 41;42 42;43 43;44 255 0;NODATA 0" "D:\alaska_reclassified.tif" DATA 
Start Time: Thu Jan 03 09:23:13 2013
ERROR 999998: Unexpected Error.
Failed to execute (Reclassify).
Failed at Thu Jan 03 09:23:13 2013 (Elapsed Time: 0.00 seconds)

Wie kann ich dieses Raster-Dataset neu klassifizieren? Ich verwende ArcCatalog 10.0, Build 4000, mit aktivierter Spatial Analyst-Erweiterung.

DoggoDougal
quelle
Das Extrahieren nach Attributen scheint auch das zu tun, was ich brauche, führt aber leider zu einem weiteren "unerwarteten Fehler".
DoggoDougal
Vielleicht einen anderen Datensatz ausprobiert? Zwei Prozesse, die auf demselben Datensatz fehlschlagen, lassen Sie sich wundern ...
Chad Cooper
2
Normalerweise reclassifysollte dies ein letzter Ausweg sein, da der Umfang so allgemein ist, dass wahrscheinlich Methoden verwendet werden, die weniger effizient sind als sie erhalten werden können, wenn die Neuklassifizierung leicht arithmetisch oder logisch auszudrücken ist. Im vorliegenden Fall ist das Kriterium für die Neuklassifizierung so einfach, dass Sie es zuerst mit Conoder sogar mit geraden arithmetischen Operationen versuchen sollten (weil sie schnell sind). Zum Beispiel "grid" * ("grid" >= 41) * ("grid" <= 43)sollte es tun. RAM sollte kein Problem sein - Spatial Analyst Windows automatisch seine Raster-E / A und dies sind lokale Operationen.
whuber
1
Inlistist eine schöne Lösung (+1). Ich konnte condie RAM-Nutzung während des Vorgangs nutzen und überwachen. Es hat 180 MB nie überschritten, was kaum mehr ist als der RAM, der nur zum Starten von ArcMap verwendet wurde. Das Kacheln in ArcGIS erfolgt automatisch - Sie können es nicht einmal steuern (es sei denn, Sie programmieren auf die C / Fortran-Oberfläche). Es scheint, dass RAM-Einschränkungen von geringer Bedeutung sind.
whuber
1
@whuber, conarbeitete auch für mich, mit der Bedingung "Value" >= 41 AND "Value" <= 43. Ich hätte mich für diese Lösung entschieden, bin mir aber nicht sicher, ob zusätzliche Rasterwerte in Zukunft von Interesse sein werden. Natürlich könnte ich ORder where-Klausel eine hinzufügen , aber dann wird es komplizierter. InListscheint die einfachste Lösung in Bezug auf Lesbarkeit und Wartbarkeit zu sein.
DoggoDougal

Antworten:

9

Das erste angehängte Skript hat Ihre AK NLCD-Daten in ca. 15 Minuten erfolgreich neu klassifiziert (i7, 12 GB RAM-Maschine). Da der ursprüngliche Datensatz fast 7 GB groß ist, können Speicherprobleme auftreten. Wenn Sie nicht das gesamte Dataset in einem Block verarbeiten können, teilen Sie es vor der Neuklassifizierung mit dem zweiten Skript auf. Ich empfehle, eine kleine Teilmenge der Daten zu übernehmen (Klicken Sie mit der rechten Maustaste auf Rasterebene in Inhaltsverzeichnis> Daten> Daten exportieren> Umfang (Datenrahmen) und testen Sie das erste Skript. Wenn Sie die Parameter für den Befehl "Neu klassifizieren" gewählt haben, fahren Sie mit der Neuklassifizierung fort Laden Sie alternativ das 64-Bit- Produkt für die Hintergrundverarbeitung für ArcGIS 10.1 SP1 herunter , das hier verfügbar ist . Viel Glück.

Skript 1

# Import system modules
import arcpy
from arcpy import env
from arcpy.sa import *

# Overwrite output
env.overwriteOutput = 1

# Set environment settings
env.workspace = r'C:\temp'
Dir = env.workspace

# Set local variables
inRaster = Dir + "\\" + "nlcd_subset.img"
reclassField = "Value"
remap = RemapValue([[0, 40, 0], [41, 41],[42,42], [43,43], [44, 256, 0]])

# Check out the ArcGIS Spatial Analyst extension license
arcpy.CheckOutExtension("Spatial")

# Execute Reclassify
outReclassify = Reclassify(inRaster, reclassField, remap, "NODATA")

# Save the output 
outReclassify.save(r"C:\temp\nlcd_test.img")

Bearbeiten : Wenn Sie Ihre Daten vor der Verarbeitung aufteilen müssen, sollte dieses Skript helfen:

Skript 2

# Import system modules
import arcpy
from arcpy import env
from arcpy.sa import *

# Check out the ArcGIS Spatial Analyst extension license
arcpy.CheckOutExtension("Spatial")

# Overwrite output
env.overwriteOutput = 1

# Set environment settings
env.workspace = r'C:\temp'
Dir = env.workspace

# Set local variables
inRaster = Dir + "\\" "nlcd" + "\\" + "nlcd_ak.img"
outFolder = Dir
reclassField = "Value"
remap = RemapValue([[0, 40, 0], [41, 41],[42,42], [43,43], [44, 256, 0]])

# Split Rasters
# Equally split a large TIFF image by number of images
arcpy.SplitRaster_management(inRaster, outFolder, "split", "NUMBER_OF_TILES", "#",
                             "NEAREST", "2 2", "#", "4", "PIXELS",\
                             "#", "#")

# List rasters for processing
rasters = arcpy.ListRasters()


for ras in rasters:
    print "processing..." + ras

    # Define new name
    name = "class_" + ras  

    # Execute Reclassify
    outReclassify = Reclassify(ras, reclassField, remap, "NODATA")

    # Save the output 
    outReclassify.save(Dir + "\\" + name)
Aaron
quelle
3
Unter Leistungsgesichtspunkten wäre es interessant, einen alternativen Ansatz mit arcpy.RasterToNumPyArray () zu versuchen und die Neuklassifizierung in numpy durchzuführen. Wahrscheinlich möchten Sie das Raster aus Speichergründen ohnehin in Kacheln aufteilen, aber ich weiß, dass es mit GDAL sehr schnell geht, Numpy-Arrays neu zu klassifizieren.
DavidF
@DavidF Einverstanden, würde sich die Leistung wahrscheinlich erheblich verbessern.
Aaron
Danke für die Tipps, Aaron. Ich werde es versuchen, sobald ich eine weitere Problemumgehung abgeschlossen habe, bei der die Farbkarte ( auf die hier verwiesen wird ) entfernt werden muss. Bei dieser Methode muss auch das Raster aufgeteilt werden. Daher frage ich mich, ob die Neuklassifizierung des Originals aufgrund der Speichernutzung oder aus einem anderen Grund fehlgeschlagen ist.
DoggoDougal
@torik Kein Problem - ich gebe gerne meine zwei Cent. Ich denke, das Entfernen der Farbkarte ist nicht der richtige Weg. Ich würde mich eher auf die Aufteilung von Daten oder die 64-Bit-Hintergrundverarbeitung konzentrieren.
Aaron
@Aaron, unter Berücksichtigung der Tatsache, dass Sie Code für die Kachelung bereitgestellt haben, wie haben Sie das Teilmengenraster erstellt, mit dem Sie die abgebildeten Ergebnisse erstellt haben? Ich habe die SplitRaster-Kachelung abgeschlossen (wobei 100 Teilmengen des gesamten Raster-Datasets erzeugt wurden) und versucht, sie alle zu durchlaufen, um sie neu zu klassifizieren. Die Neuklassifizierung ist leider fehlgeschlagen, was zu derselben Meldung "Unerwarteter Fehler" führte.
DoggoDougal
4

whuber machte einen Kommentar zur Verwendung logischer Werkzeuge, um diese Neuklassifizierung auszudrücken . Nach einigem Graben stellte ich fest, dass InList als Teil des Logical Math-Toolset von Spatial Analyst meinen Bedarf erfüllte.

import arcpy

# Check out the ArcGIS Spatial Analyst extension license
arcpy.CheckOutExtension("Spatial")
from arcpy.sa import InList

# Pixel values of interest, named according to Table 2 of
#  http://landcover.usgs.gov/pdf/anderson.pdf
DECIDUOUS_FOREST = 41
EVERGREEN_FOREST = 42
MIXED_FOREST = 43

inRaster = r'D:\AK_NLCD_2001_land_cover_3-13-08\ak_nlcd_2001_land_cover_3-13-08_se5.img'
accepted_raster_values = [DECIDUOUS_FOREST, EVERGREEN_FOREST, MIXED_FOREST]
filteredAlaska = InList(inRaster, accepted_raster_values)
filteredAlaska.save(r'C:\alaska\ak_woods')

Es ist bei weitem die einfachste Lösung, die ich finden konnte, führt die schnellste aus und erfordert keine Berücksichtigung der Kachelung des Originaldatensatzes. Der verfügbare Arbeitsspeicher des Computers muss nicht berücksichtigt werden, da dieses Tool direkt von der Festplatte liest und die Ergebnisse direkt auf der Festplatte speichert.

Gefiltertes Alaska-Ergebnis mit InList

DoggoDougal
quelle
+1 Gut gemacht und eine großartige Lösung. Wie lange hat die Bearbeitung aus Neugier gedauert?
Aaron
@ Aaron, die Verarbeitung von ganz Alaska dauert 13 Minuten und 23,4 Sekunden. Die Beispieluntermenge , die eine der 100 gleich großen Teilmengen ist, die von erstellt wurden SplitRaster_management, dauert 7,04 Sekunden.
DoggoDougal
Interessant, ungefähr die gleichen Verarbeitungszeiten zwischen den beiden Methoden (dh vorausgesetzt, wir haben ähnliche Systeme ausgeführt).
Aaron
Ich habe einen Intel Core 2 Duo E6850 mit 3 GHz, 4 GB RAM und 64-Bit-Windows 7. Ich werde in Kürze eine Timing-Analyse Ihrer Lösung durchführen. Ich bin vorerst mit Arc 10.0 festgefahren, sonst würde ich die 64-Bit-Hintergrundverarbeitung untersuchen.
DoggoDougal
1

Ich habe den im ursprünglichen Beitrag erwähnten Datensatz mit einer 10.4 dev-Version von arcmap verwendet. Die Neuklassifizierung schlägt fehl, wenn das Ausgabe-Raster ein Raster ist, da die neu klassifizierten Zellenzahlen überlaufen, was im Feld COUNT einer Raster-Mehrwertsteuer gespeichert werden kann. Wenn das Ausgabe-Raster eine FGDB ist, wird es für mich in ungefähr 11 Minuten auf einem älteren 4-Core-Computer unter Windows 8 erfolgreich ausgeführt. Nicht-Grid-Rasterformate sollten funktionieren, da sie Gleitkommawerte mit doppelter Genauigkeit für das Zählfeld verwenden. Ich gehe davon aus, dass Sie mit den veröffentlichten Versionen 10.2 oder 10.3 dasselbe Verhalten erzielen sollten. Wir werden die Verwendung eines anderen Rasterformats für die Standardausgabe für Reclassify untersuchen.

jt64
quelle