chọn tỷ lệ phần trăm (75%) của một nhóm điểm dựa trên khoảng cách từ một điểm riêng biệt trong ArcGIS?


9

Đây là ArcGIS cụ thể.

Tôi có 2 shapefiles AB, điểm đầu tiên ( A) là một điểm duy nhất chứa lat lat, điểm thứ hai ( B) là vô số điểm (trên 12k) mà mỗi điểm chứa lat và long của chúng. Những gì tôi đang cố gắng làm là tự động hóa việc lựa chọn 75% số điểm của shapefile Bdựa trên khoảng cách từ shapefile A. Nói cách khác, tôi muốn chọn 75% số Bđiểm shapefile gần nhất Avới một điểm của shapefile .


Là một giải pháp lập trình được chấp nhận?
Kirk Kuykendall

BTW, tôi đã yêu cầu Esri cho phép Shapefield được sử dụng trong ITableSortCallback tùy chỉnh nhưng được cho biết không có lý do nào cho việc này. Trường hợp sử dụng này cho thấy khác.
Kirk Kuykendall

@Kirk Kuykendall Có một giải pháp lập trình thực sự sẽ được ưa thích vì đây là quá trình tôi sẽ phải lặp lại hơn 1k lần. Tôi có khoảng 1200 điểm riêng biệt và mỗi điểm đó có một shapefile khác với trung bình 12k điểm xung quanh nó. Tôi cần tìm ra một cách để dễ dàng chọn 75% điểm xung quanh gần nhất cho tất cả chúng. Làm nó bằng tay chỉ là ra khỏi câu hỏi.
Furlong

Có lẽ nhận xét này nằm ngoài phạm vi thích hợp của một nhận xét, nhưng khi nào và tại sao một phân tích như vậy sẽ hữu ích? Điều này là để làm sáng tỏ của riêng tôi; tha thứ cho sự chậm chạp của tôi
Nathanus

1
Cân nhắc sử dụng phần mềm thống kê. Nếu bạn đã hợp nhất tất cả 1200 shapefile, tạo trường id nguồn trong quá trình hợp nhất, bạn có thể nối tọa độ điểm trung tâm tương ứng với đó và tính toán tất cả khoảng cách 1200 * 12k = 14,4M. Những gì bạn cần sau đó là một danh sách các phần trăm khoảng cách thứ 75 theo id nguồn: sẽ mất khoảng mười giây với Stata (thương mại) hoặc R (nguồn mở). (Nếu bạn sử dụng ArcGIS cho việc này, hãy cho chúng tôi biết cần bao nhiêu thời gian cho việc tính toán. :-)
whuber

Câu trả lời:


5

Bạn có thể tạo Bộ đệm nhiều vòng trên shapefile A và sau đó thực hiện nối không gian của Bộ đệm để tạo hình B. Khi bạn thực hiện nối đa giác và điểm, bạn sẽ nhận được số lượng điểm trong mỗi đa giác trong thuộc tính bảng tham gia. Sau đó, bằng cách kiểm tra tổng số điểm trong bộ đệm, bạn có thể nhận được trong vòng 75% số điểm trong shapefile B.

Một cách tiếp cận hơi khác sẽ là kịch bản này trong Python và kiểm tra 75% trong một vòng lặp, nhưng nếu đó là phép tính tắt một lần, bạn có thể không cần điều đó.


4
Sẽ đơn giản hơn, nhanh hơn và chính xác hơn để thực hiện nối không gian từ A đến B, tính toán phần tư thứ ba của trường [khoảng cách] kết quả và chọn tất cả các bản ghi nhỏ hơn khoảng cách đó.
whuber

Tôi không biết có thể tham gia điểm không gian! Tôi đồng ý, đây sẽ là một cách tốt hơn để làm điều đó.
djq

@Andy Ngược lại, tham gia là mối quan hệ điểm gần nhất. Nó không dựa trên bất kỳ thuộc tính được lập bảng nào cả. Ngoài ra, trong phần mềm Arc * (quay lại ArcView 2), khoảng cách sẽ được tự động tính toán do kết nối.
whuber

1
@whuber, tôi biết! Do đó, rút ​​lại (câu lệnh đã xóa!) Tôi giả sử bạn có thể làm điều đó bằng cách tham gia bảng thuộc tính (và tự tính toán khoảng cách) nhưng điều đó sẽ không cần thiết trong bối cảnh. Tôi đoán điểm tôi muốn nhắc lại là nó chỉ đơn giản là tính toán khoảng cách giữa 1 điểm, không cần lặp hoặc đệm hay thủ tục lặp.
Andy W

1
@Furlong Nếu bạn đọc những ví dụ về không gian Tham gia: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//... bạn có thể nhận được một ý tưởng làm thế nào để chạy này trong python. Sau đó, vấn đề là chạy qua bảng thuộc tính và chọn các giá trị phù hợp với tiêu chí của bạn
djq

4

1200 điểm (hoặc thậm chí lên đến nói điểm 12M?) Tôi chỉ muốn đặt chúng vào bộ nhớ như một Bộ sưu tập Generic - trong trường hợp này một SortedList của danh sách . Điều này có thể được đơn giản hóa bằng cách chỉ bỏ qua các điểm khi bạn gặp tình huống có nhiều điểm có cùng khoảng cách với điểm gốc. Ngoài ra, để thực hiện, hãy cân nhắc sử dụng hàm băm thay vì Sắp xếp danh sách và sắp xếp một lần sau khi chèn tất cả các khoảng cách. Điều đó sẽ mất thêm một vài dòng mã mặc dù (?).

Tôi không có thời gian để kiểm tra điều này, nhưng c # này có thể giúp bạn bắt đầu:

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

Một kịch bản xử lý địa lý Python là một lựa chọn rõ ràng:

  1. Sử dụng công cụ Khoảng cách điểm để tính khoảng cách từ các tính năng của bạn trong lớp tính năng B (tham số "Tính năng đầu vào" của công cụ) đến điểm trong lớp tính năng A (tham số "Tính năng gần" của công cụ).
  2. Sắp xếp bảng theo khoảng cách tính toán.
  3. Chọn 75% đối tượng đầu tiên trong bảng đầu ra (cột "Input_FID") và sử dụng các đối tượng đó để thực hiện lựa chọn của bạn từ các tính năng ban đầu trong lớp tính năng B.

2

Tôi đã có vấn đề này một vài năm trước. Tôi thấy việc giữ dữ liệu dưới dạng 'dữ liệu phẳng' dễ dàng hơn, lặp qua tất cả dữ liệu và tính toán thủ công khoảng cách, sau đó chiếm 75% hàng đầu (tôi thực sự giữ 10% hàng đầu). Sau đó tôi đã làm tương tự trong ArcIMS bằng cách tính toán khoảng cách của họ và mất nhiều thời gian hơn.

Bộ đệm là một chi phí rất lớn, nhưng các phép tính toán học là một 'sở trường của người chơi. Nếu bạn đệm 12k điểm, tôi nghĩ bạn sẽ gặp vấn đề về hiệu suất.


Tôi [@Mapperz] đã xóa các nhận xét - hướng dẫn về công cụ mod đã gắn cờ bài đăng này vì nó đã biến thành cuộc cãi lộn vô nghĩa ...
Mapperz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.