ポイント属性に基づいてアトラスを作成する方法は?


9

基本的に、ポイントレイヤーのカテゴリフィールドに基づいてアトラスを作成したいと考えています。

つまり、カテゴリフィールド「プロビジョニング」を持つ保育プロバイダーのポイントレイヤーがあります。このフィールドの各機能を「アフタースクールクラブ」、「朝食クラブ」などで分類しました。次に、各カテゴリを反復し、それぞれのポイントのみを表示する一連のマップを作成します。放課後クラブの1つのマップ、朝食クラブの1つのマップなど。範囲は微妙に異なる場合があります。

一つずつやってもいいのですが、各カテゴリーの範囲に基づいてアトラスを作成する方法はあるのでしょうか?(私は明らかな何かを見逃していると思います:))

あるいは、ポリゴンレイヤーの作成を自動化し、それをアトラスの隠されたカバレッジとして使用する方法はありますか?

編集:私はこれで少し進歩しました-ルールベースのスタイリングを使用して、現在のアトラスカバレッジ機能に関連する機能のオンとオフを切り替えることができます。あなたがしたいすべてが異なるポイントのセットを示すことであるならば、それは実際にうまく働きます。私は今、それを配色と反応的な伝説に結びつけることを検討しています。



ありがとう、クリス。それは、元のアトラスの各エリアに対してサブアトラスを実行できるかどうかを尋ねているように見えますか?たとえば、それぞれ4ページの4つの領域?(私は求められていたものを追うのに苦労しましたが)
JonoPatterson

1
いいえ、基本的にはどちらもマップシリーズを作成します。シリーズは同じマップ範囲とベース情報を示していますが、それぞれに異なる機能があります。私のコメントでは、ページ定義クエリと呼ばれるものを介して、ArcGISでそれを実行する方法について説明しています。つまり、アトラス/マップブックの各ページには、そのページに表示されるレイヤー/フィーチャを決定する定義クエリがあります。彼は一連のシリーズを望んでいます。しかし、QGISがそのような機能をまだ提供しているかどうかはわかりません(提供していない回答/コメントを読んだと思いましたが、今は見つかりません)。
クリスW

また、あなたのケースでは、同じ属性を共有する各ポイントの範囲に基づいて境界ボックスを生成し、それらをインデックス機能として使用することができますが、異なるポイントグループを自動的にオン/オフする問題が残っています。それらを別々のレイヤーに分割したとしても、何らかの定義クエリがないと、特定のページでこれらのポイントをオフにする方法はありません。
クリスW

はい、あなたの死者。これもこの1つのgis.stackexchange.com/questions/121802/…の繰り返しです。手動で実行する必要があるかもしれません。
JonoPatterson 2015

回答:


9

私は最終的にこれを私の目的のために解決したので、それが誰かを助ける場合に私が思いついた解決策は次のとおりです:

本質的にこれを行うpythonスクリプト(これの最後にあるもの)を記述します。

  1. 対象のポイントレイヤーフィールドで一意のカテゴリを特定する
  2. 各カテゴリについて、すべての一致するポイントを選択し、このセットの範囲を確立します
  3. 各エクステントについて、キー属性「CategoryName」を持つ空白のアトラスカバレッジレイヤーに新しいポリゴンを生成します

これにより、アトラスカバレッジレイヤーに、関心のある各カテゴリに対して1つのポリゴンが次のように表示されます。 アトラスカバレッジレイヤー

通常どおりアトラスと印刷コンポーザーを構成します-機能のオンとオフの問題のみを残します。

このため、オプションの正確なセットを算出するのは少し試行錯誤です。

  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冒頭で述べたpythonスクリプトを共有する場合、これはこれまでで最高の回答です;)
Bernd V.

Okはこれを行います-ラフな準備ができているため、いくつかの調整が必要になります(何年もコーディングを行っていません!)。それを行うための最良の方法は何ですか-コードボックスに貼り付けるだけですか?
JonoPatterson 2015

@JonoPattersonスクリプトをありがとうございました。初心者の私にとって、これはすでに非常によく見えます:)。私はこれがすぐに必要になると確信しています。
Bernd V.

式の例は少し間違っています-「$ atlasfeatureid」ではなく「$ atlasfeature」である必要があります
ndawson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.