ArcGIS'te ayrı bir noktadan olan mesafeye bağlı olarak bir grup noktanın yüzdesini (% 75) seçme?


9

Bu ArcGIS'e özgüdür.

2 nokta şekil dosyaları var Ave Bbirincisi ( A) bir lat uzun içeren tek bir nokta, ikincisi ( B) her biri kendi lat ve uzun içeren çok sayıda nokta (12k üzerinde). Yapmaya çalıştığım şekil Bdosyasından uzaklığa bağlı olarak şekil dosyasının noktalarının % 75'inin seçimini otomatikleştirmek A. Başka bir deyişle, şekil dosyası Bnoktalarına şekil dosyasının en yakın% 75'ini seçmek istiyorum A.


Programlı bir çözüm kabul edilebilir mi?
Kirk Kuykendall

BTW, Esri'nin Shapefield'ın özel bir ITableSortCallback içinde kullanılmasına izin vermesini istedim, ancak bunun için bir gerekçe olmadığı söylendi. Bu kullanım durumu aksini gösterir.
Kirk Kuykendall

@Kirk Kuykendall Evet, aslında 1k kez tekrar etmem gerekecek bir program olduğu için aslında programlı bir çözüm tercih edilecektir. Kabaca 1200 ayrı noktam var ve bu noktaların her birinin etrafında ortalama 12k nokta bulunan başka bir şekil dosyası var. Hepsi için çevre noktaların en yakın% 75'ini kolayca seçmenin bir yolunu bulmam gerekiyor. Manuel olarak yapmak sadece söz konusu değil.
Furlong

Belki de bu yorum bir yorumun kapsamı dışındadır, ancak böyle bir analiz ne zaman ve neden yararlı olur? Bu benim kendi açıklamam için; yavaşlığımı affet.
Nathanus

1
İstatistiksel yazılım kullanmayı düşünün. Birleştirme sırasında bir kaynak kimliği alanı oluşturarak 1200 şekil dosyasının tümünü birleştirecekseniz, buna karşılık gelen merkezi nokta koordinatlarına katılabilir ve tüm 1200 * 12k = 14.4M mesafelerini hesaplayabilirsiniz. İhtiyacınız olan şey, kaynak kimliğe göre 75. persentillerin bir listesidir: Stata (ticari) veya R (açık kaynak) ile yaklaşık on saniye sürer. (Bunun için ArcGIS kullanıyorsanız, hesaplama için ne kadar zaman harcadığımızı bize bildirin. :-)
whuber

Yanıtlar:


5

Bir yapabiliriz Çoklu Zil Tampon şekil dosyası A ve sonra bir bir çokgen ve noktaların katılmak hacimsel yaptığınızda B. şekil dosyası için Tampon katılmak hacimsel yaparsanız, özelliğinde her çokgenin noktaların sayısının bir sayımını almak birleştirme tablosu. Daha sonra, arabelleklerdeki toplam nokta sayısını inceleyerek, şekil dosyası B'deki noktaların% 75'ini elde edebilirsiniz.

Biraz farklı bir yaklaşım bunu Python'da kodlamak ve bir döngüde% 75'i kontrol etmek olacaktır, ancak bir kerelik bir hesaplama ise buna ihtiyacınız olmayabilir.


4
A'dan B'ye uzamsal birleşimi gerçekleştirmek, elde edilen [mesafe] alanının üçüncü çeyreğini hesaplamak ve bu mesafeden daha az tüm kayıtları seçmek daha basit, daha hızlı ve daha doğru olacaktır.
whuber

Noktalara mekânsal olarak katılmanın mümkün olduğunu bilmiyordum! Katılıyorum, bunu yapmanın çok daha iyi bir yolu olurdu.
djq

@Andy Aksine, birleşme en yakın nokta ilişkisidir. Hiç çizelge niteliğine dayalı değildir. Ayrıca, Arc * yazılımında (ArcView 2'ye geri dönerek), birleştirme sonucunda mesafe otomatik olarak hesaplanır.
whuber

1
@whuber, biliyorum! Bu nedenle geri çekilmiş (silinmiş deyimi!) Öznitelik tablo birleşimleri (ve mesafeyi kendiniz hesaplayarak) yapabileceğinizi varsayıyorum ama bağlam göz önüne alındığında bu gereksiz olacaktır. Tekrarlamak istediğim nokta, sadece 1 nokta arasındaki mesafeyi hesaplamak, döngü veya tampon yok veya yinelemeli prosedürler gerekli olduğunu tahmin ediyorum.
Andy W

1
@Furlong Spatial Join örneğini okursanız: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… bunu python'da nasıl çalıştıracağınıza dair bir fikir edinebilirsiniz. Ardından, özellik tablosundan geçerek ve ölçütlerinize uyan değerleri seçme meselesidir
djq

4

1200 puan için (hatta yukarı veya 12M noktaları söylemek?) Ben sadece bir Genel Collection olarak belleğe koymak istiyorum - bu durumda bir de SortedList ait listelerin . Bu, başlangıç ​​noktasından aynı mesafede olan birden fazla noktaya sahip bir duruma geçtiğinizde noktaları atlayarak basitleştirilebilir. Ayrıca, performans için SortedList yerine hashtable kullanmayı ve tüm mesafeleri ekledikten sonra bir kez sıralamayı düşünün . Bu birkaç satır daha alır (?).

Bunu test etmek için zamanım yoktu, ama bu c # başlayabilir:

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 coğrafi işleme komut dosyası bariz bir seçimdir:

  1. Özellik sınıfı B'deki özelliklerden (aracın "Giriş Özellikleri" parametresi) özellik sınıfı A'daki noktaya (aracın "Yakın Özellikler" parametresi) olan mesafeyi hesaplamak için Nokta Mesafesi aracını kullanın.
  2. Tabloyu hesaplanan mesafeye göre sıralayın.
  3. Çıktı tablosundaki ("Input_FID" sütunu) nesne tanıtıcılarının ilk% 75'ini seçin ve özellik sınıfı B'deki orijinal özelliklerden seçiminizi yapmak için bunları kullanın.

2

Birkaç yıl önce bu sorunu yaşadım. Verileri 'düz veri' olarak tutmayı, tüm veriler arasında dolaşmayı ve mesafeyi manuel olarak hesaplamayı, sonra en üst% 75'i almayı daha kolay buldum (aslında en üst% 10'u korudum). Aynı şeyi ArcIMS'de mesafe hesaplamalarını kullanarak yaptım ve çok daha uzun sürdü.

Arabelleğe alma çok büyük bir ek yüktür, ancak matematik hesaplamaları 'puter forte' dir. 12 bin puan tamponluyorsanız, performans sorunları yaşayacağınızı düşünüyorum.


Ben [@Mapperz] yorumları sildi - anlamsız
çekişmeye
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.