Có cách nào để chọn một thuộc tính từ lớp đa giác và chèn giá trị vào trường ảo của lớp điểm bằng cách sử dụng "bên trong" trong máy tính trường không?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Có cách nào để chọn một thuộc tính từ lớp đa giác và chèn giá trị vào trường ảo của lớp điểm bằng cách sử dụng "bên trong" trong máy tính trường không?
CASE
WHEN within($geometry, geometry_polygon) THEN attribute_polygon
END
Câu trả lời:
Ra khỏi hộp, máy tính trường không hỗ trợ các phép nối không gian trên các lớp tính năng. Nhưng, nếu bạn xem bài đăng của NathanW trên trình soạn thảo chức năng cho các biểu thức qgis, bạn sẽ có thể nhận ra rằng chúng ta có thể tạo kịch bản tương tác dữ liệu của chính mình.
Kịch bản sau đây sẽ cho phép bạn thể hiện những gì bạn đang theo đuổi. Nó hoạt động bằng cách lặp qua tất cả các tính năng trên lớp đa giác và nếu có một phép nối không gian, thì tham chiếu dữ liệu bảng từ cột được chỉ định:
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
Dưới đây là một ví dụ về một lớp đa giác mà bạn có thể có. Tôi cũng đã tạo một lớp điểm tương ứng mà bạn sẽ thấy trong hình ảnh cuối cùng.
Lưu ý, nếu bạn muốn sử dụng một cột riêng biệt, bạn phải thay đổi đối số thứ hai để khớp với tên cột trong bộ dữ liệu đa giác. Ví dụ: bạn có thể sử dụng cột 'AreaNumber', nhưng sẽ phải khớp với loại cột trong cài đặt máy tính trường.
Bạn có thể thấy rằng giá trị cột mặc định đã được áp dụng khi không có nối không gian và các giá trị khác khớp với dữ liệu chính xác. Lưu ý kịch bản tôi đã đưa ra sẽ chỉ tham gia vào trận đấu đầu tiên . Bạn sẽ cần tạo một số logic nghiệp vụ khác nếu đa giác của bạn bị chồng chéo.
Nó có thể được thực hiện trong Field Calculator với chức năng aggregate()
. Trong lớp điểm tạo trường mới với biểu thức máy tính trường như thế này:
aggregate(
layer:= 'polygon_layer_name',
aggregate:='concatenate',
expression:=joining_field_name,
concatenator:=', ',
filter:=intersects($geometry, geometry(@parent))
)
Trường hợp layer
tên lớp đa giác được viết như chuỗi, aggreagate
là hàm tổng hợp (cũng có thể được sử dụng, v.v.), expression
là trường từ các giá trị sẽ được lấy, concatenator
đang nối chuỗi ký tự (phải được đặt, ngay cả trong trường hợp này) và filter
lọc các tính năng dựa trên trên biểu thức (trong trường hợp này xen kẽ hình học lớp với hình học của lớp cha).
Để biết thêm thông tin, hãy kiểm tra tài liệu tổng hợp của QGIS .
Đối với các bản cập nhật tự động có thể được sử dụng các trường ảo hoặc bạn có thể đặt biểu thức làm Giá trị mặc định trong cài đặt Biểu mẫu thuộc tính trong Thuộc tính lớp ( Tài liệu cài đặt biểu mẫu thuộc tính ).
geometry(@parent)
) chỉ được hỗ trợ từ QGIS 3 trở đi. Chỉ trong trường hợp bất cứ ai đọc cái này vẫn đang sử dụng 2.18 ...