GIS Shape Datein Ordner und Unterordner auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@Karamell:

anbei eine Möglichkeit, wie man das implementieren könnte:

(ungetestet)

Code: Alles auswählen

import arcpy
from pathlib import Path

FILENAMES = Path(r'C:\Test').rglob('*.shp')


def set_coordinate_status(message, *args):
    try:
        for status in args:
            arcpy.SetParameterAsText(status[0], status[1])
        arcpy.AddMessage(message)
    except SinnvolleArcpyException:
        arcpy.AddPrintMessage("Irgendwas sinnvolles")


def resolve_shape(path):
    try:
    	dsc = arcpy.Describe(path)
    	sr = dsc.spatialReference
    	return sr.name.lower()
    except SinnvolleArcpyException:
        arcpy.AddPrintMessage("Irgendwas sinnvolles")

def main():
    for shape in FILENAMES:
        prj = resolve_shape(shape)

        if prj.find("_stateplane_") > -1:
            message = "Coordinate system is StatePlane"
            set_coordinate_status(
                message, ((1, 'false'), (2, 'true'))
            )
        elif prj == "unknown":
            message = "To continue, first define a coordinate system!"
            set_coordinate_status(
                message, ((1, 'true'), (2, 'false'))
            )
        else:
            message = "Coordinate system is not StatePlane or Unknown"
            set_coordinate_status(
                message, ((1, 'false', 2, 'false'))
            )


if __name__ == '__main__':
    main()
Ich würde dazu auch die Doku von Arcpy konsultieren und die Exceptions durch etwas sinnvolles ersetzen (also Fehler, welche man erwarten könnte, nicht einfach pauschal alles abfangen. Ich habe das mal hier offengelassen, weil ich keine Lust habe Cookies von Arcpy's Dokuseite zu akzeptieren)

So kannst du beliebig viele Shapes ohne großes Zutun verarbeiten und reichst basierend auf den Ergebnissen was auch immer in `prj` so *drin* ist die notwendigen Parameter an eine Funktion die dann die Status setzt.

EDIT: noch als Ergänzung zu dem Beispiel in der Doku. Das Beispiel ist nicht gut, da es massiv gegen DRY verstößt (Don't repeat yourself), vorallem weil hier halt nichts generisch aufgebaut ist. Die Wartung von solchem Code wird zur Hölle.
When we say computer, we mean the electronic computer.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt `prj.find("_stateplane_") > -1` nimmt man `in`. Da `set_coordinate_status` in allen if-Blöcken vorkommt, kann man diesen Aufruf mit zusätzlichen Variablen nach hinten schieben, die Bedeutung von true und false ist mir aber nicht bekannt, so dass mir keine guten Namen dafür einfallen.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@Sirius3: danke für die Hinweise, ich hab's angepasst. Was `true` oder `false` hier macht und wie das für arcpy relevant ist; kein blassen.

Code: Alles auswählen

import arcpy
from pathlib import Path

FILENAMES = Path(r'C:\Test').rglob('*.shp')


def set_coordinate_status(message, *args):
    try:
        for status in args:
            arcpy.SetParameterAsText(status[0], status[1])
        arcpy.AddMessage(message)
    except SinnvolleArcpyException:
        arcpy.AddPrintMessage("Irgendwas sinnvolles")


def resolve_shape(path):
    try:
    	describe = arcpy.Describe(path)
    	spatial_reference = dsc.spatialReference
    	return spatial_reference.name.lower()
    except SinnvolleArcpyException:
        arcpy.AddPrintMessage("Irgendwas sinnvolles")


def main():
    for shape in FILENAMES:
        prj = resolve_shape(shape)

        if "_stateplane_" in prj:
            message = "Coordinate system is StatePlane"
            statuses =  ((1, 'false'), (2, 'true'))
            )
        elif prj == "unknown":
            message = "To continue, first define a coordinate system!"
            statuses = ((1, 'true'), (2, 'false'))
            )
        else:
            message = "Coordinate system is not StatePlane or Unknown"
            statuses = ((1, 'false', 2, 'false'))
            )
        set_coordinate_status(message, statuses)


if __name__ == '__main__':
    main()
When we say computer, we mean the electronic computer.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich hätte das noch in erster_wert, zweiter_wert aufgespalten und statuses im Aufruf zusammengebaut.
Karamell
User
Beiträge: 14
Registriert: Montag 19. November 2018, 09:53

pathlib ersetzt mir in diesem Fall das os.walk?
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

Ja.
When we say computer, we mean the electronic computer.
Karamell
User
Beiträge: 14
Registriert: Montag 19. November 2018, 09:53

Ich habe es jetzt geschafft, pathlib zu installieren. War gar nicht so einfach, denn ich habe erst noch pip installiert. Da ich Python Version 2.7 nutze war das gar nicht so einfach, aber mit viel Suchen gings dann, zumindest habe ich kein Fehlermeldung bekommen.
Morgen gehts dann weiter. Ich danke Euch für Euren Input!
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das mit Python 2.7 hätte man wissen müssen. Alternativ geht auch die glob()-Funktion aus dem gleichnamigen Modul. Das gibt es in der Standardbibliothek von Python 2.7.
Karamell
User
Beiträge: 14
Registriert: Montag 19. November 2018, 09:53

O_o, ich habe in der Arbeit auch pip und pathlib installiert. Nun komme ich aber an arcpy nicht mehr dran.
Am besten, ich deinstalliere Python komplett und versuche es dann über .glob...
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

Die Installation zusätzlicher Pakete sollte aber eigentlich keinen Einfluss darauf haben. Was heißt in deiner Welt denn "komme ich aber an arcpy nicht mehr dran"? Gibt's Fehlermeldungen? Welche IDE verwendest du? Man sollte generell für jedes Projekt eine eigene virtuelle Umgebung erstellen, um die projektspezifischen Abhängigkeiten sauber von der systemweiten Python-Umgebung zu trennen.

pip und virtualenv sind für sowas gemacht.
When we say computer, we mean the electronic computer.
Karamell
User
Beiträge: 14
Registriert: Montag 19. November 2018, 09:53

Ich habe einen einfachen Code, mit dem ich arcpy anspreche. Das hat nach der Installation von pip und pathlib nicht mehr funktioniert. Das Modul arcpy existiert nicht.
Ich habe versucht, arcpy neu zu installieren, das hat alles nicht funktioniert.
Nachdem ich Python deinstalliert habe und ArcGIS repariert ging es wieder.
Karamell
User
Beiträge: 14
Registriert: Montag 19. November 2018, 09:53

Hurra! Es scheint zu klappen, zumindest bekomme ich keine Fehlermeldung mehr zurück. Danke Dir @sls für die Vorlage! Ich musste noch ein paar Sachen modifizieren. Ob die Benennung der Exeptions sinnvoll ist, weiß ich auch nicht.
Wenn ich allerdings statt "arcpy.AddMessage" "print" eingebe, bekomme ich immer die Meldung, dass kein Koordinatensystem vorhanden ist, was in meinen Testordner bei nur 2 von 3 Shapes der Fall sein sollte. Da muss ich also noch weiter probieren. Und das ganze dann noch in ArcGIS implementieren...

Code: Alles auswählen

import arcpy
import glob

FILES = glob.glob(r'C:\Test\*.shp')

def set_coordinate_status(message, *args):
    try:
        for status in args:
            arcpy.SetParameterAsText(status[0], status[1])
        arcpy.AddMessage(message)
    except Exception:
        arcpy.AddError("koordinaten status failed")

def resolve_shape(path):
    try:
    	describe = arcpy.Describe(path)
    	spatial_reference = dsc.spatialReference
    	return spatial_reference.name.lower()
    except Exception:
        arcpy.AddError("Resolve failed")

def main():
    for shape in FILES:
        prj = resolve_shape(shape)

        if prj is None:           
           arcpy.AddMessage = "To continue, first define a coordinate system!"
           statuses = ((1, 'true'), (2, 'true'))
                      
        else:            
            arcpy.AddMessage = "Coordinate system is known"
            statuses = ((1, 'false'), (2, 'false'))
            
        set_coordinate_status(shape, statuses)

if __name__ == '__main__':
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Karamell: Ich denke mal Du solltest ``print`` vertrauen, denn was Du da mit `AddMessage` machst, unterscheidet sich von dem was Du mit `AddError` machst, und das sieht mir irgendwie korrekter aus. Also Aufrufen und nicht durch Zuweisung einer Zeichenkette überschreiben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Karamell
User
Beiträge: 14
Registriert: Montag 19. November 2018, 09:53

@__blackjack__, ok, aber wenn ich 'print' nehme, gibt es mit trotzdem die falsche Meldung aus.
Vielleicht eine wirklich doofe Frage: was hat der Code zu bedeuten den Du gepostet hast?
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Karamell: Das ist kein Code sondern die Einschaltmeldung meines Lieblingscomputers, und meine Signatur. Sollte ich vielleicht doch mal wieder ändern. Leider kann man Code nicht kleiner machen oder in einer anderen Farbe einbinden, und soweit ich das gesehen habe auch nicht auf andere Weise eine nicht-proportionale Schriftart wählen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten