วิธีการโหลดเอาท์พุทหน่วยความจำจากการประมวลผล QGIS?


11

อัลกอริทึมการประมวลผลจำนวนมากมีตัวเลือกในการบันทึกผลลัพธ์เป็นหน่วยความจำ หากวิ่งจากกล่องเครื่องมือสิ่งนี้จะใช้ได้เพราะคุณสามารถทำเครื่องหมายในช่อง "เปิดไฟล์เอาต์พุตหลังจากเรียกใช้อัลกอริทึม"

มองไปที่ซอร์สโค้ดสำหรับ QGIS Postprocessing.handleAlgorithmResultsรหัสสำหรับการโหลดชั้นหน่วยความจำที่ดูเหมือนว่าจะมีการกำหนดไว้ในการทำงาน ฟังก์ชันใช้การเข้าถึงalg.outputsรายการและทำสิ่งต่อไปนี้:

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:
                # ... 

เมื่อคุณเรียกใช้อัลกอริทึมการประมวลผลจากคอนโซลมีวิธีโหลดเลเยอร์โดยไม่ต้องเข้าถึงวัตถุนี้หรือไม่? ฉันวิ่งได้

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

หรือแม้กระทั่ง

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

อย่างไรก็ตามฉันไม่สามารถหาวิธีที่จะคว้าผลลัพธ์ที่ได้

คำตอบ:


15

ฉันพบมันแล้ว ใช้processing.runandloadซึ่งโหลดเลเยอร์เอาต์พุตลงในสารบัญหลังจากเรียกใช้อัลกอริทึม

processing.runandload("qgis:intersection", layer1, layer2, "memory:myLayerName")
layer = QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]
# Should do error checking as well, but this works!!

1
ฉันรู้สึกทึ่งกับคำตอบที่คุณพบ คุณรู้หรือไม่ว่ามีวิธีการคล้ายกันในการสร้างเลเยอร์หน่วยความจำและสามารถเข้าถึงได้โดยไม่ต้องใช้ runandload? ฉันหวังว่าจะทำการประมวลผลการโพสต์บางอย่างเกี่ยวกับการส่งออกการประมวลผลก่อนที่จะเพิ่มผ้าใบ - และสงสัยว่าดังกล่าวเป็นไปได้ ...
Katalpa

1
ฉันไม่สามารถหาได้ทีละคนอย่าบอกว่ามันเป็นไปไม่ได้ ... ฉันคิดว่าคุณสามารถโหลดและซ่อนมันได้ถ้ามันช่วยได้
สติน

หากคุณไม่สามารถหาชื่อเลเยอร์โดยใช้QgsMapLayerRegistry.instance().mapLayersByName("memory:myLayerName")[0]ลอง:QgsMapLayerRegistry.instance().mapLayers()
เพื่อน Che

@ Katpa คุณสามารถลองใช้การประมวลผลรันอัลกอล ("qgis: intersection", layer1, layer2, 'out.shp')
ละคร

4

เป็นวิธีที่ถูกต้องอธิบายไว้ในเอกสารประกอบ http://docs.qgis.org/2.14/es/docs/user_manual/processing/console.html

โค้ดถัดไปใช้งานได้ในหน่วยความจำทั้งหมดยกเว้นรหัสสุดท้ายที่โหลด

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.runalg เป็นกุญแจสำคัญและค่าเป็นเส้นทางชั่วคราว คุณสามารถเห็นคีย์ด้วย processeing.alghelp ("การประมวลผลชื่อ") เป็นการประมวลผล, alghelp ("grass: r.drain")bu['OUTPUT']OUTPUT

กลับ

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>

ในกรณีนี้คีย์คือผลลัพธ์ให้ระวังตัวอักษรตัวใหญ่ที่คุณต้องเขียนเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์ใหญ่ในกรณีนี้ไม่ใช่ตัวพิมพ์ใหญ่


โปรดหลีกเลี่ยงคำตอบที่ซ้ำกัน ( gis.stackexchange.com/a/211730/8104 ) ตามนโยบาย Stack Exchange รายละเอียดเพิ่มเติม: meta.stackexchange.com/q/104227
แอรอน

นี่คืออันที่ทำงานให้ฉันในที่สุด ข้อมูลที่สำคัญที่ขาดหายไปที่อื่น ๆ คือการที่คุณสามารถผ่านoutput['OUTPUT']เส้นทางไปQgsVectorLayerกับของprovider_name "ogr"สิ่งนี้จะอ่านในพา ธ . shp และสร้างเลเยอร์ในหน่วยความจำ วิธีนี้ไม่เพิ่มเลเยอร์ลงในรีจิสทรีดังนั้นจึงไม่กะพริบในแผงเลเยอร์
Nick K9

อ้างอิงหน้าคู่มือที่คุณอ้างอิง "วิธี runalg ส่งคืนพจนานุกรมที่มีชื่อเอาต์พุต (รายการที่แสดงในคำอธิบายอัลกอริทึม) เป็นคีย์และพา ธ ไฟล์ของเอาต์พุตเหล่านั้นเป็นค่า" ดังนั้นวิธีนี้ดูเหมือนจะไม่ใช้เลเยอร์หน่วยความจำ - ผลลัพธ์ระดับกลางทั้งหมดจะถูกเก็บไว้ในระบบไฟล์
Håvard Tveite

0

ฉันไม่แน่ใจว่าสิ่งนี้จะช่วยคุณในบริบทของคุณหรือไม่ (คุณต้องการรันโค้ดเป็นแบบสแตนด์อโลนหรือภายใน QGIS หลังจากประมวลผลการประมวลผลเสร็จสิ้นหรือไม่?) ถ้ามันหลังคุณสามารถสอบถามการโหลดQGsVector-และQGsRasterlayerวัตถุได้อย่างง่ายดายโดยดูในรีจิสทรี 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

โดยทั่วไปทุกเลเยอร์จะต้องมีแหล่งที่หนึ่งบนฮาร์ดไดรฟ์แม้ว่าผลลัพธ์จะถูกเพิ่มหลังจากการประมวลผลเสร็จสิ้นการคำนวณ หากคุณดูข้อมูลเมตาของเลเยอร์คุณสามารถค้นหาแหล่งที่มาที่แท้จริงของเลเยอร์ (หากมาจากการประมวลผลโดยปกติที่ใดที่หนึ่งในโฟลเดอร์ชั่วคราว)


ขอบคุณสำหรับคำตอบ. ฉันคิดว่ามีgetLayersByNameฟังก์ชั่นสำหรับรีจีสทรีแผนที่แล้ว แต่ฉันต้องการเรียกใช้อัลกอริทึมจากคอนโซลตัวเองดังนั้นสิ่งนี้จะไม่ช่วยได้จริง (ชั้นหน่วยความจำไม่เคยโหลดลงในรีจิสทรีนั่นคือสิ่งที่ฉันพยายามทำ) . แต่คุณกำลังบอกว่าไม่มีประโยชน์ที่จะใช้เอาต์พุตหน่วยความจำเมื่อเปรียบเทียบกับการส่งผ่านNoneและการสร้างไฟล์ชั่วคราว? คุณแน่ใจเหรอ
สติน

Noneจะถูกส่งถ้าเลเยอร์ไม่พบในรีจิสตรี มันไม่ได้สร้างไฟล์ชั่วคราวและคุณต้องตรวจสอบมันด้วยตนเอง ฉันใช้ฟังก์ชันนี้เพื่อค้นหาเลเยอร์ที่โหลดภายใน QGIS ไม่สามารถช่วยคุณออกไปข้างนอกในคอนโซล
Curlew

ฉันคิดว่าคุณเข้าใจผิดผมได้พูดคุยเกี่ยวกับการผ่านNoneการprocessing.runalgเป็นพารามิเตอร์การส่งออกซึ่งผมเชื่อว่าจะสร้างไฟล์ที่ส่งออกชั่วคราว
สติน

FYI: เพิ่งเจอฟังก์ชั่น QgsMapLayerRegistry อีกครั้งมันถูกเรียกว่าmapLayersByName
Oystein
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.