ArcPyでPythonデータ構造とクラスをどのように使用していますか?


16

この質問は、プログラミングに関する私の無知を明らかにするかもしれませんが、ArcPy内でさまざまなpythonデータ構造をどのように使用しているかに興味があります。

このページには、Pythonのデータ構造がリストされています。リストをGISに実装する方法(フィーチャクラスのリスト、フィーチャタイプのリスト、データフレームのリストなど)を理解しています。セットの使用方法も理解しています(重複を削除するため)。タプル、辞書、およびその他のデータ構造をArcPy内に実装する人々はどのようになっていますか?また、リストしていないリストやセットの他の例はありますか?

さらに、間違いなく、人々はArcPyでカスタムクラスを作成しています。どのような状況や状況でこれらが必要ですか?例を提供できますか?組み込みのarcpyクラスを継承するカスタムクラスを作成している人はいますか?

私はこれらの質問すべてに答える必要はありません。人々がGISでPythonをどのように使用しているか、どのワークフローがこれらのカスタマイズを必要としているのか、興味があります。


4
興味深い質問ですが、これには決定的な答えはありません。コミュニティwikiである必要があります。
RK

回答:


14

複数の入力を受け取る多くのarcpy関数は、Pythonリストオブジェクトを受け入れます。

たとえば、Dissolve_management関数はディゾルブするフィールド名のリストを受け入れます。

arcpy.Dissolve_management("taxlots", "C:/output/output.gdb/taxlots_dissolved",
    ["LANDUSE", "TAXCODE"], "", "SINGLE_PART", "DISSOLVE_LINES")

タプルは不変であるため、要素の順序や数を変更する必要がない場合、リストの代わりにタプルを使用できます。これらは、タイムスタンプの要素やポイントの座標など、異種ではあるが関連するデータの断片に役立つデータ構造です。リストを簡単に変更サイズは、再注文することができながら、あなたは、多くの場合、タプルは属性の固定数で明確な記録となったタプルのリストが表示されます(ソート)など、この参照してくださいStackOverflowの質問を用途に関する詳細は、リスト対タプル。

辞書は、比較的小さいが頻繁に使用されるキーと値のペアのセットをメモリにキャッシュする高速ルックアップテーブルとして使用できます。この興味深い例を、ArcGISフォーラムで見ました:http : //forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

結合の代わりに辞書を使用すると、計算が3.5時間から15分に短縮されました。

より簡単な例は、略称の州名(CA)を持つ属性を持つ100万の住所レコードがある場合ですが、表示目的で適切な名前(カリフォルニア)を綴りたい場合、この辞書をルックアップテーブルとして使用できます。完全な州名フィールドに入力します。

自分でarcpyで使用するためにPythonでクラスを記述する必要はありませんでしたが、そのようなユースケースがないと言っているわけではありません。クラスは、何らかの入力(データ)を操作する一連の密接に関連する関数(動作)があり、それらのデータと動作をオブジェクト指向の方法で使用できるようにする場合に役立ちますが、これはおそらくビジネスロジック固有であり、arcpyとは関係ありません。


7

Blah238はこのトピックをよくカバーしているので、自分の仕事からいくつかの例を追加します。私は多くの空港データを開発しており、定期的に行わなければならないことの1つは、滑走路から測量された滑走路のセンターラインポイントに沿って順番に読み取られることです。これらのポイントは既に(GISデータベースで)整頓されていると思いますが、そうなることはめったにありません。中心線のポイントは、中心線に沿って10フィートごとに発生し、両側に10フィート離れた2つの他の調査ポイントの列が隣接しています。たくさんのポイントがあり、そして通常はすべてがデータベースごとに混在しています。私がスクリプトで行っていることでは、通常、属性によって(または必要に応じて空間的に)センターラインポイントを選択し、それぞれの座標を読み取り、結果をPythonリストにダンプするのが最も簡単です。その後、ソート、ポップ、リバースなどを行うことができます。

同様に、Python辞書を広範囲に使用します(おそらく、一部の人が承認するよりもはるかに多く)。空港の各滑走路端に3Dユニットベクトルのセットを作成する必要があり、スクリプト内でこれらに常にアクセスし、多くのスクリプトでこれを行います。定期的にアクセスする他の多くのデータも辞書に保存しています。リストと同様に、それらは高速で柔軟です。強くお勧めします。

Blah238のように、クラスに関する限り、作成する必要はありません。おそらく、スクリプトでクラスが優先される場合がいくつかありますが、実際にはそれらの場所を特定できませんでした。より多くのプログラミング経験がある人は、おそらくすぐにそれらを見つけるでしょう。


5

私も辞書が大好きです -いつも使ってください。このメソッドは、いくつかの空間参照プロパティを取得し、それらをすべて辞書に保存します。

def get_coord_sys(self, in_dataset):
    """Get and return info on dataset coord sys/projection"""
    spatial_ref = arcpy.Describe(in_dataset).spatialReference
    # Get spatial ref props and put in dictionary
    spat_ref_dict = {}
    spat_ref_dict["name"] = spatial_ref.name
    spat_ref_dict["type"] = spatial_ref.type
    spat_ref_dict["gcs_code"] = spatial_ref.GCSCode
    spat_ref_dict["gcs_name"] = spatial_ref.GCSName
    spat_ref_dict["pcs_code"] = spatial_ref.PCSCode
    spat_ref_dict["pcs_name"] = spatial_ref.PCSName
    return spat_ref_dict

このメソッドスニペットは、2つのフィーチャクラスからポイントジオメトリを抽出し、後でジオメトリを使用していくつかのトリガーを実行します。

def build_fields_of_view(self):
        """For all KOPs in a study area, build left, right, center FoV triangles"""
        try:    
            fcs = {os.path.join(self.gdb, "WindFarmArray"):[], os.path.join(self.gdb, "KOPs"):[]}
            # Build a dict of WTG and KOP array geometries, looks like:
            #  {'KOPs': [[1, -10049.2697098718, 10856.699451165374], 
            #            [2, 6690.4377855260946, 15602.12386816188]], 
            #   'WindFarmArray': [[1, 5834.9321158060666, 7909.3822339441513], 
            #                     [2, 6111.1759513214511, 7316.9684107396561]]}
            for k, v in fcs.iteritems():
                rows = arcpy.SearchCursor(k, "", self.sr)
                for row in rows:
                    geom = row.shape
                    point = geom.getPart()
                    id = row.getValue("OBJECTID")
                    v.append([id, point.X, point.Y])   

            kops = fcs[os.path.join(self.gdb, "KOPs")] # KOP array
            wtgs = fcs[os.path.join(self.gdb, "WindFarmArray")] # WTG array

私が現在取り組んでいる多くのことは、ベクターフィーチャクラスとラスターから座標と属性を抽出し、GISデータが何であるかさえ知らない別のソフトウェアにデータをプッシュできるようにすることです。そのため、このためにリストと辞書をたくさん使用します。


答えてくれてありがとう。これらの場合、なぜ辞書が他のデータ構造よりも良い選択なのですか?
フェスター

キーで値を呼び出すことができるようにしたいだけです。
チャドクーパー

2
dictが望ましいもう1つの理由は、順序付けされていないため、リストよりもはるかに高速に読み取られるためです。したがって、非常に長いリストは、エントリが多い場合、処理にもう少し時間がかかる場合があります。
-ndimhypervol

@gotanuki確かに、大きなリストを使用する必要がある場合は、リストよりも高速であるため、代わりにタプルを使用します。
チャドクーパー

2

回答をまとめながらこれを読んでいくつかの編集を行う必要がありました。

私はPythonの専門家ではありませんが、クラスを使用する背後にある考え方は、データ構造に関連するだけでなくメソッドを集中化する多数のメソッドを持つオブジェクトをインスタンス化できるということです。また、クラスとモジュールには可変スコープの利点もあります。上記のリンクはこの点に多少到達しています。

私はfeatureLayerと呼ばれるクラスを持っています(おそらくPythonのような名前ではありません...まだ学習しています)。できます

sys.path.append(r"\\Path\To\Scripts")
import gpFuncs as gpF
fc = arcpy.GetParameterAsText(0)
featureLayer = gpF.featureLayer(fc)
points = featureLayer.featureVerticesToPoints(featureid, "", first_and_last)

これを行うための定義は、フィーチャ、パーツ、および頂点を反復するクラスメソッドです。次に、ポイントオブジェクトをfeatureLayerインスタンスに変換し、クラスにある他の処理を実行できます。

正しく構築されたクラスは機能を無効化すべきだと思います。たとえば、すぐにリファクタリングを開始して、すべてのフィーチャレイヤーが持つメソッドと属性を持つfeatureLayerクラスを作成します。次に、そこから継承して、featureLayersのすべての属性/メソッドを継承するが、ポリゴンなどの特定のジオメトリタイプでインスタンス化するfeatureLayerStrictクラスインスタンスを構築します。



0

私は主にVB .netで働いていますが、Pythonとarcpyをますます使用しています。VBでは、コードを読みやすくするためにEnumを使用してみました。以前のバージョンのpythonはEnumを実装していなかったため、ハックはいくつかのプロパティを公開するクラスを作成することでした。多くの例がStack Overflowで説明されています。ここでは、最新バージョンのpythonがこれらを実装しているように見えます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.