ArcGISの1つの個別のポイントからの距離に基づいて、ポイントのグループのパーセンテージ(75%)を選択しますか?


9

これはArcGIS固有です。

2つのポイントシェープファイルがAありB、最初の(A)は緯度経度を含む単一のポイント、2番目(B)は緯度と経度をそれぞれ含む多数のポイント(12k以上)です。私がやろうとしていることは、シェープファイルBからの距離に基づいてシェープファイルのポイントの75%の選択を自動化することですA。言い換えると、シェープファイルBポイントの75%に最も近く、シェープファイルAの1ポイントを選択します。


プログラムによるソリューションは受け入れられますか?
カークカイケンダル

ところで、EsriにShapefieldをカスタムITableSortCallbackで使用することを許可するように要求しましたが、これには正当な理由がないと言われました。この使用例は、それ以外の場合を示しています。
カークカイケンダル

@Kirk Kuykendallはい、これは私が1,000回以上繰り返す必要があるプロセスであるため、プログラムによるソリューションが実際に推奨されます。およそ1200の個別のポイントがあり、それらのポイントのそれぞれに、平均して12,000ポイントの周りに別のシェープファイルがあります。それらすべての周囲のポイントの75%に最も近いものを簡単に選択する方法を見つける必要があります。手動で行うことは問題外です。
ファーロング、

おそらくこのコメントはコメントの適切な範囲外ですが、そのような分析が役立つのはいつ、なぜでしょうか?これは私自身の説明のためです。私の遅さを許してください。
Nathanus、

1
統計ソフトウェアの使用を検討してください。1200個すべてのシェープファイルをマージし、マージ中にソースIDフィールドを作成する場合、対応する中心点座標をそれに結合し、すべての1200 * 12k = 14.4Mの距離を計算できます。次に必要なのは、ソースID別の距離の75パーセンタイルのリストです。これは、Stata(商用)またはR(オープンソース)で約10秒かかります。(ArcGISを使用する場合は、計算にかかる時間を教えてください。:-)
whuber

回答:


5

シェープファイルAで複数リングバッファーを作成してから、バッファーをシェープファイルBに空間結合することができます。ポリゴンとポイントの空間結合を実行すると、属性内の各ポリゴンのポイント数がカウントされます結合のテーブル。次に、バッファー内のポイントの総数を調べることにより、シェープファイルBのポイントの75%以内を取得できます。

少し異なるアプローチは、これをPythonでスクリプト化し、ループ内で75%をチェックすることですが、1回限りの計算の場合は、それが必要ない場合があります。


4
AからBへの空間結合を実行し、結果の[距離]フィールドの3番目の四分位数を計算し、その距離よりも短いすべてのレコードを選択する方が、簡単、高速、かつ正確です。
whuber

ポイントを空間的に結合できることを知りませんでした!私は同意します、これはそれを行うはるかに良い方法でしょう。
djq

@Andy逆に、ジョインは最も近いポイントの関係です。これは、表形式の属性にまったく基づいていません。また、Arc *ソフトウェア(ArcView 2に戻る)では、結合の結果として距離が自動的に計算されます。
whuber

1
@whuber、私は知っている!したがって、格納された(削除されたステートメント!)属性テーブルの結合(および距離を自分で計算する)によってそれを実行できると思いますが、コンテキストを考慮すると不要です。繰り返したいのは、1点間の距離を計算するだけで、ループやバッファ、反復手順は必要ないということです。
Andy W、

1
@Furlong空間結合の例:help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#// … を読むと、Pythonでこれを実行する方法のアイデアを得ることができます。次に、属性テーブルを実行し、基準に一致する値を選択することです
djq

4

1200ポイント(または最大で12Mポイント?)の場合は、それらをジェネリックコレクション(この場合はリストのSortedList)としてメモリに格納します。これは、原点から同じ距離にある複数のポイントがある状況に遭遇したときに、ポイントをスキップするだけで簡略化できます。また、パフォーマンスのために、SortedListの代わりにハッシュテーブルを使用し、すべての距離を挿入した後に1回ソートすることを検討してください。ただし、コードを数行追加する必要があります(?)。

これをテストする時間はありませんでしたが、このc#で始められるかもしれません。

private void SelectNTile(string layer1, string layer2, double nTile)
{
    var fLayer1 = FindLayer(ArcMap.Document.FocusMap, "LayerWithLotsofPoints");
    var fLayer2 = FindLayer(ArcMap.Document.FocusMap, "LayerWithOneSelectedPoint");
    IFeature feat = GetSingleFeature(fLayer2);
    var distList = MakeDistList(fLayer1.FeatureClass,(IPoint)feat.ShapeCopy);
    // assume not many points exactly same distance
    var nRecs = (int)(distList.Count * nTile); // nTile would be 0.75 for 75%
    var Oids = new List<int>();
    foreach (KeyValuePair<double, List<int>> kvp in distList)
    {
        Oids.AddRange(kvp.Value);
        if (Oids.Count > nRecs)
            break;
    }
    var fSel = fLayer1 as IFeatureSelection;
    var OidArray = Oids.ToArray();
    fSel.SelectionSet.AddList(Oids.Count, ref OidArray[0]);                
}

private SortedList<double, List<int>> MakeDistList(IFeatureClass fc, IPoint pnt)
{
    var outList = new SortedList<double, List<int>>();
    var proxOp = pnt as IProximityOperator;
    IFeatureCursor fCur = null;
    try
    {
        fCur = fc.Search(null, true); // recycling is faster, we just need OIDs
        IFeature feat;
        while ((feat = fCur.NextFeature()) != null)
        {
            double dist = proxOp.ReturnDistance(feat.Shape);
            if (!outList.ContainsKey(dist))
                outList.Add(dist, new List<int> { feat.OID });
            else
                outList[dist].Add(feat.OID);  // this should rarely happen
        }
    }
    catch
    {
        throw;
    }
    finally
    {
        if (fCur != null)
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
    }
    return outList;
}
private IFeature GetSingleFeature(IFeatureLayer fLayer)
{
    var fSel = fLayer as IFeatureSelection;
    if (fSel.SelectionSet.Count != 1)
        throw new Exception("select one feature in " + fLayer.Name + " first");
    var enumIDs = fSel.SelectionSet.IDs;
    enumIDs.Reset();
    IFeature feat = fLayer.FeatureClass.GetFeature(enumIDs.Next());
    return feat;
}
private IFeatureLayer FindLayer(IMap map, string name)
{
    throw new NotImplementedException();
}

4

Pythonジオプロセシングスクリプトは明らかな選択肢です。

  1. ポイント距離ツールを使用して、フィーチャクラスBのフィーチャ(ツールの「入力フィーチャ」パラメーター)からフィーチャクラスAのポイント(ツールの「近接フィーチャ」パラメーター)までの距離を計算します。
  2. 計算された距離でテーブルを並べ替えます。
  3. 出力テーブル( "Input_FID"列)のオブジェクトIDの最初の75%を選択し、それらを使用して、フィーチャクラスBの元のフィーチャから選択します。

2

この問題は数年前にありました。データを「フラットデータ」として保持し、すべてのデータをループ処理して距離を手動で計算し、上位75%(実際には上位10%を保持)を使用する方が簡単であることがわかりました。その後、距離計算を使用してArcIMSでも同じことを行いましたが、はるかに長くかかりました。

バッファリングは莫大なオーバーヘッドですが、数学の計算は「得意先の強み」です。12kポイントをバッファリングすると、パフォーマンスの問題が発生すると思います。


私は[@Mapperz]がコメントを削除しました-modのツールガイドラインがこの投稿にフラグを付けました。無意味な
口論
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.