Jak załadować wyjście pamięci z przetwarzania QGIS?

11

Wiele algorytmów przetwarzania ma opcję zapisywania danych wyjściowych jako pamięci. W przypadku uruchomienia z przybornika działa to dobrze, ponieważ można zaznaczyć pole „Otwórz plik wyjściowy po uruchomieniu algorytmu”.

Patrząc na kod źródłowy QGIS, kod do ładowania warstwy pamięci wydaje się być zdefiniowany w funkcji Postprocessing.handleAlgorithmResults. Funkcja korzysta z dostępu do alg.outputslisty i wykonuje następujące czynności:

for out in alg.outputs:
    progress.setPercentage(100 * i / float(len(alg.outputs)))
    if out.hidden or not out.open:
        continue
    if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
        try:
            if out.value.startswith('memory:'):
                layer = out.memoryLayer                                # NOTE!!
                QgsMapLayerRegistry.instance().addMapLayers([layer])   # NOTE!!
            else:
                # ... 

Czy po uruchomieniu algorytmów przetwarzania z konsoli można załadować warstwę bez dostępu do tego obiektu? mogę biec

processing.runalg("qgis:intersection", layer1, layer2, "memory:")

lub nawet

processing.runalg("qgis:intersection", layer1, layer2, "memory:myLayerName")

Nie mogę jednak znaleźć sposobu na uzyskanie wynikowego wyniku.

Oysteina
źródło

Odpowiedzi:

15

Aaa i znalazłem to. Użyj processing.runandload, która ładuje warstwę wyjściową do spisu treści po uruchomieniu algorytmu.

processing.runandload("qgis:intersection", layer1, layer2, "memory:myLayerName")
layer = QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]
# Should do error checking as well, but this works!!
Oysteina
źródło
1
Intryguje mnie odpowiedź, którą znalazłeś. Czy wiesz, czy istnieje podobny sposób tworzenia warstwy pamięci - i że masz do niej dostęp bez implementacji uruchamiania i uruchamiania? Mam nadzieję, że zrobię post przetwarzanie na wyjściu przetwarzania przed dodaniem go do płótna - i zastanawiałem się, czy to w ogóle możliwe ...
Katalpa
1
Nie mogłem go znaleźć na raz, nie mówiąc, że jest to niemożliwe ... Myślę, że możesz go załadować i ukryć, jeśli to pomoże.
Oystein
Jeśli nie możesz znaleźć nazwy warstwy za pomocą, QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]spróbuj tego:QgsMapLayerRegistry.instance().mapLayers()
Towarzysz Che
@Katalpa możesz spróbować, processing.runalg ("qgis: intersection", layer1, layer2, 'out.shp')
dramat
4

jest to właściwy sposób, wyjaśniono to w dokumentacji http://docs.qgis.org/2.14/es/docs/user_manual/processing/console.html

następny kod działa w pamięci wszystkie oprócz ostatniego, który jest ładowany

MDT=path/mdt.tif
drain=processing.runalg("grass:r.drain",MDT,"",(pun),False,False,False,"%f,%f,%f,%f"% (xmin, xmax, ymin, ymax),0,-1,0.00100,None)
vect=processing.runalg("grass:r.to.vect",drain['output'],0,False,"%f,%f,%f,%f"% (xmin, xmax, ymin, ymax),0,None)
bu=processing.runalg("qgis:fixeddistancebuffer",vect['output'],Metros_afecta,1,False,None)
buf=bu['OUTPUT']
bufe= QgsVectorLayer(buf,"area", "ogr")
#the last load the layer 
QgsMapLayerRegistry.instance().addMapLayers([bufe])

processing.runalgzwraca słownika w tym przypadku bu['OUTPUT']. OUTPUTJEST KLUCZEM, a wartością jest ścieżka tymczasowa. Możesz zobaczyć klucz z przetwarzaniem.alghelp („przetwarzanie nazw”) jako przetwarzaniem, alghelp („grass: r.drain”)

powrót

processing.alghelp("grass:r.drain")
ALGORITHM: r.drain - Traces a flow through an elevation model on a raster map.
input <ParameterRaster>
coordinate <ParameterString>
vector_points <ParameterMultipleInput>
-c <ParameterBoolean>
-a <ParameterBoolean>
-n <ParameterBoolean>
GRASS_REGION_PARAMETER <ParameterExtent>
GRASS_REGION_CELLSIZE_PARAMETER <ParameterNumber>
GRASS_SNAP_TOLERANCE_PARAMETER <ParameterNumber>
GRASS_MIN_AREA_PARAMETER <ParameterNumber>
output <OutputRaster>

w tym przypadku klucz jest wyprowadzany , uważaj na duże litery, które musisz pisać dużymi literami lub bez, w tym przypadku nie dużymi literami.

kortowanie
źródło
Unikaj podwójnych odpowiedzi ( gis.stackexchange.com/a/211730/8104 ), zgodnie z zasadami stosu wymiany. Więcej informacji: meta.stackexchange.com/q/104227
Aaron
To był ten, który ostatecznie dla mnie zadziałał. Kluczem informacji, której brakowało innym, że można przejść output['OUTPUT']ścieżkę QgsVectorLayerz provider_nameo "ogr". Odczyta to ścieżkę .shp i utworzy warstwę w pamięci. To podejście nie dodaje warstwy do rejestru, więc nie jest flashowane w panelu warstw.
Nick K9,
Według strony podręcznika, do której się odwołujesz: „Metoda runalg zwraca słownik z nazwami wyjściowymi (tymi pokazanymi w opisie algorytmu) jako kluczami, a ścieżki plików tych danych wyjściowych jako wartości”. Dlatego wydaje się, że to podejście nie wykorzystuje warstw pamięci - wszystkie wyniki pośrednie zostaną zapisane w systemie plików.
Håvard Tveite
0

Nie jestem pewien, czy to pomoże ci w twoim kontekście (czy chcesz uruchomić swój kod jako samodzielny czy w QGIS po zakończeniu algorytmu przetwarzania?). Jeśli jest to drugie, możesz łatwo wyszukać załadowane obiekty QGsVector-i przeszukać QGsRasterlayerobiekty, przeglądając rejestr QGIS MapLayer.

# General function to retrieve a layer with a given name
def getLayerByName( layerName ):
  layerMap = QgsMapLayerRegistry.instance().mapLayers()
  for name, layer in layerMap.iteritems():
    if layer.name() == layerName:
        if layer.isValid():
          return layer
        else:
          return None

Zasadniczo wszystkie warstwy muszą mieć źródło gdzieś na dysku twardym, nawet jeśli wynik zostanie dodany dopiero po zakończeniu obliczeń przez algorytm przetwarzania. Jeśli spojrzysz na metadane warstw, możesz znaleźć faktyczne źródło warstwy (jeśli pochodzi ona z przetwarzania jej zwykle gdzieś w folderze tymczasowym)

Kulik
źródło
Dziękuję za Twoją odpowiedź. Myślę, że jest już getLayersByNamefunkcja rejestru rejestru, ale chcę uruchomić algorytm z konsoli, więc to naprawdę nie pomoże (warstwa pamięci nigdy nie jest ładowana do rejestru, to właśnie próbuję zrobić) . Ale czy mówisz, że korzystanie z wyjścia pamięci nie ma przewagi nad przekazywaniem Nonei generowaniem pliku tymczasowego? Jesteś pewien?
Oystein,
Nonejest przekazywany, jeśli warstwy nie można znaleźć w rejestrze. Nie tworzy pliku tymczasowego i i tak musisz go sprawdzić ręcznie. Korzystam z tej funkcji, aby wyszukiwać załadowane warstwy w QGIS. Nie mogę ci pomóc na zewnątrz w konsoli.
Curlew,
Chyba źle, rozmawiałem o przejściu Nonedo processing.runalgjako parametr wyjściowy, który moim zdaniem tworzy plik wyjściowy temp.
Oystein,
FYI: Właśnie natrafiłem na funkcję QgsMapLayerRegistry, nazywa sięmapLayersByName
Oystein