มีวิธีการเลือกแอตทริบิวต์จากรูปหลายเหลี่ยมเลเยอร์และแทรกค่าลงในเขตข้อมูลเสมือนของชั้นจุดโดยใช้ "ภายใน" ในเครื่องคิดเลขฟิลด์หรือไม่?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
มีวิธีการเลือกแอตทริบิวต์จากรูปหลายเหลี่ยมเลเยอร์และแทรกค่าลงในเขตข้อมูลเสมือนของชั้นจุดโดยใช้ "ภายใน" ในเครื่องคิดเลขฟิลด์หรือไม่?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
คำตอบ:
เครื่องคิดเลขภาคสนามไม่รองรับการรวมเชิงพื้นที่ในเลเยอร์คุณลักษณะ แต่ถ้าคุณดูที่โพสต์ของ NathanW ในตัวแก้ไขฟังก์ชั่นสำหรับการแสดงออก qgisคุณจะสามารถระบุได้ว่าเราสามารถเขียนสคริปต์การโต้ตอบข้อมูลของเราเอง
สคริปต์ต่อไปนี้จะช่วยให้คุณแสดงสิ่งที่คุณต้องการ มันทำงานได้โดยการวนซ้ำผ่านฟีเจอร์ทั้งหมดบนเลเยอร์รูปหลายเหลี่ยมและหากมีการรวมเชิงพื้นที่ให้อ้างอิงข้อมูลตารางจากคอลัมน์ที่ระบุ:
from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
allfeatures = None
index = QgsSpatialIndex()
indexMade = 0
refLayer = None
@qgsfunction(args="auto", group='Custom')
def spatialJoinLookup(layerName, refColumn, defaultValue, geom, feature, parent):
if geom is None:
return defaultValue
# globals so we don't create the index, refLayer more than once
global allfeatures
global index
global indexMade
global refLayer
# Get the reference layer
if refLayer is None:
for layer in iface.mapCanvas().layers():
if layerName == layer.name():
refLayer = layer
break
if refLayer is None:
raise Exception("Layer [" + layerName + "] not found")
# Create the index if not exists
if indexMade == 0:
index = QgsSpatialIndex()
allAttrs = layer.pendingAllAttributesList()
layer.select(allAttrs)
allfeatures = {feature.id(): feature for (feature) in refLayer.getFeatures()}
for f in allfeatures.values():
index.insertFeature(f)
indexMade = 1
# Use spatail index to find intersect
fid = None
ids = index.intersects(geom.boundingBox())
for id in ids:
fid = id
break # Only get the first match.
if fid is not None:
return allfeatures[fid].attribute(refColumn)
# Default
return defaultValue
ด้านล่างนี้เป็นตัวอย่างของเลเยอร์รูปหลายเหลี่ยมที่คุณอาจมี ฉันได้สร้างเลเยอร์จุดที่สอดคล้องกันซึ่งคุณจะเห็นในภาพสุดท้าย
หมายเหตุถ้าคุณต้องการใช้คอลัมน์แยกคุณต้องเปลี่ยนอาร์กิวเมนต์ที่สองเพื่อให้ตรงกับชื่อคอลัมน์ในชุดข้อมูลรูปหลายเหลี่ยม ตัวอย่างคุณสามารถใช้คอลัมน์ 'AreaNumber' แต่จะต้องตรงกับประเภทคอลัมน์ในการตั้งค่าเครื่องคิดเลข
คุณจะเห็นว่ามีการใช้ค่าคอลัมน์เริ่มต้นในกรณีที่ไม่มีการรวมเชิงพื้นที่และอีกรายการหนึ่งจับคู่ข้อมูลที่ถูกต้อง โปรดทราบว่าสคริปต์ที่ฉันให้จะเข้าร่วมในนัดแรกเท่านั้น คุณจะต้องสร้างตรรกะทางธุรกิจอื่น ๆ หากรูปหลายเหลี่ยมของคุณทับซ้อนกัน
ก็สามารถทำได้ในการคำนวณสนามaggregate()
ที่มีฟังก์ชั่น ในเลเยอร์พอยต์สร้างฟิลด์ใหม่ด้วยนิพจน์ฟิลด์เครื่องคิดเลขดังนี้:
aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)
โดยที่layer
ชื่อเลเยอร์รูปหลายเหลี่ยมที่เขียนเหมือนสตริงaggreagate
คือฟังก์ชันรวม (สามารถใช้รวมได้เช่นกัน) expression
คือฟิลด์จากค่าที่จะถูกนำมาconcatenator
เข้าร่วมสตริงอักขระ (ต้องตั้งค่าแม้ในกรณีนี้) และfilter
เป็นคุณสมบัติการกรองตาม ในการแสดงออก (ในกรณีนี้ interesects เรขาคณิตชั้นกับเรขาคณิตของผู้ปกครองชั้น)
สำหรับข้อมูลเพิ่มเติมตรวจสอบเอกสาร Aggregates QGIS
สำหรับการอัปเดตอัตโนมัติสามารถใช้ฟิลด์เสมือนหรือคุณสามารถตั้งค่านิพจน์เป็นค่าเริ่มต้นในการตั้งค่าแบบฟอร์มคุณสมบัติในคุณสมบัติเลเยอร์ ( เอกสารการตั้งค่ารูปแบบคุณสมบัติ )
geometry(@parent)
) ได้รับการสนับสนุนจาก QGIS 3 เป็นต้นไป ในกรณีที่ทุกคนที่อ่านข้อความนี้ยังคงใช้ 2.18 ...