포인트 속성을 기반으로 아틀라스를 만드는 방법은 무엇입니까?


9

본질적으로 포인트 레이어의 범주 필드를 기반으로 아틀라스를 만들고 싶습니다.

즉, 범주 "프로비저닝"을 가진 보육 제공자의 포인트 계층이 있습니다. 이 필드의 각 기능을 "After School Club", "Breakfast Club"등으로 분류했으며 이제 각 범주를 반복하고 각각의 포인트 만 표시하는 맵 세트를 생성하려고합니다. 방과후 클럽지도 1 개, 조식 클럽지도 1 개 등. 범위는 미묘하게 다를 수 있습니다.

하나씩 할 수는 있지만 각 범주의 범위에 따라 아틀라스를 생성하는 방법이 있어야하는 것 같습니다. (나는 명백한 것을 놓치고 있다고 생각합니다 :))

또는 다각형 레이어 생성을 자동화하고이를 아틀라스의 숨겨진 범위로 사용하는 방법이 있습니까?

편집 : 나는 이것으로 약간의 발전을 이루었습니다. 규칙 기반 스타일을 사용하여 현재 아틀라스 범위 기능과 관련된 기능을 켜고 끌 수 있습니다. 원하는 다른 점을 표시하는 것만으로도 실제로 잘 작동합니다. 나는 이제 그것을 색 구성표와 반응 형 범례에 다시 연결하려고합니다.


1
이것은 기본적으로 gis.stackexchange.com/questions/155143
Chris W

고마워 크리스-하지만 확실하지 않습니다. 원래 아틀라스의 각 영역에 대해 하위 아틀라스를 수행 할 수 있는지 묻는 것 같습니다. 예를 들어 각각 4 페이지 씩 4 개의 영역이 있습니까? (필요한 사항을 따르려고 노력했지만)
JonoPatterson

1
아니요, 기본적으로 둘 다지도 시리즈를 만들려고합니다. 이 시리즈는 동일한 맵 범위와 기본 정보를 보여 주지만 각각의 기능은 다릅니다. 저의 의견은 페이지 정의 쿼리라고하는 것을 통해 ArcGIS에서 그것에 대해 이야기하고 링크를 제공합니다. 그는 일련의 시리즈를 원합니다. 여기서 당신은 단일 시리즈를 원합니다. 그러나 QGIS가 아직 그러한 기능을 제공하는지 여부는 알 수 없습니다 (답변 / 댓글을 읽지 않았다고 생각했지만 지금은 찾을 수 없습니다).
크리스 W

또한 귀하의 경우 동일한 속성을 공유하는 각 점의 범위를 기반으로 경계 상자를 생성 한 다음 색인 기능으로 사용할 수 있지만 여전히 다른 점 그룹을 자동으로 켜고 끄는 문제가 있습니다. . 레이어를 별도의 레이어로 분리하더라도 정의 쿼리가 없으면 주어진 페이지에서 해당 포인트를 끌 수있는 방법이 없습니다.
크리스 W

네 당신의 죽음. 또한이 하나의 gis.stackexchange.com/questions/121802/… 의 반복 이므로 수동으로 수행해야 할 수도 있습니다.
JonoPatterson

답변:


9

나는 마침내 내 목적을 위해 이것을 해결 했으므로 여기에 누군가를 도울 수있는 해결책이 있습니다.

본질적으로 이것을 수행하는 파이썬 스크립트를 작성하십시오 (이 끝에 광산).

  1. 관심 포인트 레이어 필드에서 고유 범주를 식별
  2. 각 범주에 대해 모든 일치점을 선택하고이 세트의 범위를 설정하십시오.
  3. 각 익스텐트에 대해 키 속성이 "CategoryName"인 빈 아틀라스 범위 레이어에 새 다각형을 생성합니다.

이것은 다음과 같이 각 관심 카테고리에 대해 하나의 다각형으로 아틀라스 커버리지 레이어를 주었다 아틀라스 커버리지 레이어

기능을 켜고 끄는 문제 만 남기고 평소대로 아틀라스 및 인쇄 작성기를 구성합니다.

이를 위해 정확한 옵션 세트를 해결하는 것은 약간의 시행 착오입니다.

  1. 아래 표현식을 사용하면 현재 아틀라스 기능의 CategoryName 필드에 현재 보유 된 값을 얻을 수 있습니다

    attribute ($atlasfeature, 'CategoryName') 
    
  2. 이것을 사용하여 라인을 따라 점 레이어에 대한 규칙 기반 스타일을 만듭니다.

    attribute ($atlasfeature, 'CategoryName') = PointCategory AND PointCategory = "RedDots"
    
  3. 또한 다른 모든 사람들이 투명 해 지도록하는 규칙이있었습니다

    attribute ($atlasfeature, 'CategoryName') IS NOT PointCategory
    

표시된 규칙

아틀라스로 이것을 테스트하면 정말 효과적입니다. 마지막으로 동일한 방법을 사용하여 표시된 레이블을 조작하고 레이블을 동적으로 만들고 테이블을 적절하게 필터링하십시오. 모든지도에서 모든 범례 항목을 원하지 않는 경우 '지도 내용으로 범례 필터링'을 선택하는 것도 매우 효과적입니다.

최종 아틀라스 세트 :

기능 기반 아틀라스

편집-요청 한대로 내 스크립트는 다음과 같습니다.

    from PyQt4.QtCore import *

#main script----------------------------------------------
    #set up the layer references - you will need to change this
targetlayer=QgsMapLayerRegistry.instance().mapLayer("AtlasExtents20150727154732521")
eylayer = QgsMapLayerRegistry.instance().mapLayer("Early_Years_Providers20150727152919862")

#establish the unique categories 
names = getUniqueAttributes(eylayer, 'Mapping_La')

#get a set of boxes
boxset = getBoundings(eylayer, names)

#ensure layer is emptied, then add bounding boxes
deleteBoxes(targetlayer)
createBoxes(targetlayer, boxset)
 #end main script----------------------------------------------   


 #------functions-------#
#gets unique set of attributes - returns a set()
def getUniqueAttributes(layer, fieldname):
    values = set()
    for feature in layer.getFeatures():
        values.add(feature[fieldname])
    return values

#quickly selects all points on a layer, given a query 
def selectionQuick(layer, queryitem):
    layer.removeSelection ()

    #hardcoded field name
    expr = QgsExpression( "\"Mapping_La\" = '" + queryitem +"'")
    it = layer.getFeatures( QgsFeatureRequest( expr ) )
    ids = [i.id() for i in it]
    layer.setSelectedFeatures( ids )

#for a set of unique items, get bounding boxes 
def getBoundings(layer, itemset):
    bboxes = {}
    for itemname in itemset:
        selectionQuick(layer,itemname)
        box = layer.boundingBoxOfSelected()
        bboxes[itemname] = box
    return bboxes

#for a layer create a bunch of boxes
def createBoxes(layer, boxes):
    id=0
    for boxkey in boxes:
        id = id +1
        box=boxes[boxkey]
        feat = QgsFeature(layer.pendingFields())
        geom = QgsGeometry.fromRect(box)
        feat.setAttribute('id', id)
        #hardcoded field name
        feat.setAttribute('CareType', boxkey)
        feat.setGeometry(geom)
        (res, outFeats) = layer.dataProvider().addFeatures([feat])

def deleteBoxes(layer):
        ids = [f.id() for f in layer.getFeatures()]
        layer.dataProvider().deleteFeatures( ids )

3
@JonoPatterson 당신이 지금 처음에 언급 한 파이썬 스크립트를 공유하고 싶다면, 이것이 가장 좋은 답이 될 것입니다;)
Bernd V.

Ok는 이것을 할 것입니다-거친 n 준비가되어 있으므로 약간의 조정이 필요합니다 (수년간 코딩을하지 않았습니다!). 가장 좋은 방법은 코드 상자에 붙여 넣는 것입니까?
JonoPatterson

@JonoPatterson 스크립트에 감사드립니다. 초보자에게는 이것이 이미 매우 좋아 보입니다 :). 나는 이것이 곧 필요할 것이라고 확신한다.
Bernd V.

예제 표현이 약간 잘못되었습니다. "$ atlasfeatureid"가 아니라 "$ atlasfeature"
ndawson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.