Làm thế nào để tham khảo một lớp khác trong máy tính trường?


26

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

nhập mô tả hình ảnh ở đây


1
Tại sao không sử dụng plugin 'Công cụ lấy mẫu điểm' cho việc này?
Jakob

Bởi vì tôi cần cập nhật động khi tạo điểm mới hoặc di chuyển điểm hiện có.
Biển âm lịch

Bạn sẽ tốt hơn khi viết kịch bản tương tác này thay vì dựa vào các công cụ trong hộp.
nagytech

Thật không may, tôi không có bất kỳ kinh nghiệm về kịch bản.
Biển âm lịch

@LunarSea Tôi đã viết một ví dụ dưới đây để bạn làm theo, nhưng bạn có thể phải điều chỉnh nó để phù hợp với nhu cầu của bạn.
nagytech

Câu trả lời:


22

Các phép nối không gian có sẵn trong máy tính trường sau khi cài đặt plugin refFifts.

geomwithin(targetLayer,targetField)

Plug-in đơn giản hơn nhiều so với sử dụng tập lệnh tùy chỉnh. Cảm ơn!
jpmc26

geomwithin ('targetLayer', 'targetField').
Raja

19

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

Ví dụ về lớp đa giác

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.

nhập mô tả hình ảnh ở đây

Cách sử dụng biểu thức

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.

nhập mô tả hình ảnh ở đây

Kết quả

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.

nhập mô tả hình ảnh ở đây


Rất cám ơn, tập lệnh của bạn đang hoạt động tốt khi sử dụng 'geom' thay vì 'hình học' trong câu lệnh 'if' đầu tiên. Tham gia hình học theo cách này có thể khá hữu ích, ví dụ như để tạo nhiều nhãn trên đa giác.
Biển âm lịch

Xin lỗi, tôi không biết làm thế nào tôi bỏ lỡ điều đó. Hy vọng rằng không có vấn đề về hiệu suất - tôi chỉ thử nó với một tập hợp nhỏ các bản ghi.
nagytech

Chỉ có hơn 100 điểm tính năng QGIS đấu tranh với các vấn đề hiệu suất. Thêm một tính năng điểm mới thực sự là một nỗi đau thậm chí không có tính năng điểm nào được hiển thị trong khung vẽ chính. Nếu không, khi phóng to QGIS sẽ tăng tốc. Tôi đã thử 'CASE KHI $ scale <10000 THEN spatialJoinLookupI (' Polygons ',' AreaName ',' none ', $ hình học) END' nhưng nó không hoạt động. Có bất cứ điều gì tôi có thể làm để cải thiện hiệu suất?
Âm lịch

@LunarSea Tôi đã cập nhật chức năng sử dụng chỉ mục không gian. Nó nên được nhanh hơn hợp lý.
nagytech 6/07/2015

Cảm ơn bạn đã giúp đỡ. Sự tham gia không gian bây giờ nhanh hơn nhiều nhưng thật không may là một cái gì đó không hoạt động đúng. Tôi nhận được kết quả khác nhau cho các điểm trong một và cùng một đa giác.
Âm lịch

8

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 layertên lớp đa giác được viết như chuỗi, aggreagatelà hàm tổng hợp (cũng có thể được sử dụng, v.v.), expressionlà 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à filterlọ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 ).

nhập mô tả hình ảnh ở đây


2
Cần lưu ý rằng các chức năng không gian (có 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 ...
she_weed

Cảm ơn bạn. Hoạt động như một lá bùa.
mặc dù không gian
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.