Tìm cạnh tối thiểu đến khoảng cách cạnh của đa giác bằng ArcGIS Desktop?


9

Tôi có một bản đồ khoảng 3000 đa giác trong ArcGIS 10. Tôi đang tìm kiếm khoảng cách giữa mỗi người trong số họ. Tôi biết cách thực hiện bằng cách sử dụng tọa độ lat và long của centroid, nhưng tôi đang tìm khoảng cách đường thẳng ngắn nhất từ ​​cạnh gần nhất của một đa giác đến cạnh gần nhất của đa giác khác. Có ý kiến ​​gì không?

Câu trả lời:


11

Đó là một đoạn mã đẹp, nhưng gần như không đẹp bằng (giả sử bảng của bạn nằm trong tọa độ địa lý, nếu không chỉ xóa các phôi thành địa lý)

CREATE TABLE mytable_distances AS
SELECT a.id, b.id, ST_Distance(a.geom::geography, b.geom::geography) as distance
FROM mytable a, mytable b;

Tôi đã đề cập rằng cơ sở dữ liệu không gian đá? Họ làm. Ồ, họ làm.


Điều này sẽ tìm thấy khoảng cách giữa các đỉnh gần nhất, nhưng không phải là các cạnh - có vẻ như GEOS không tiết lộ câu trả lời chính xác hơn này. Tuy nhiên, khá tiện dụng!
scw

1
Xin lỗi scw, bạn sai theo nhiều cách. PostGIS có tính toán khoảng cách riêng. GOES không liên quan đến điều đó. Thứ hai, nó hoàn toàn cho khoảng cách gần nhất giữa các cạnh, không chỉ các đỉnh cả về khoảng cách hình học và tính toán khoảng cách hình cầu địa lý. Paul đã viết nó.
Nicklas Avén

Để xem nó trực quan cho hình học, bạn có thể sử dụng st_shortestline trả về dòng cung cấp khoảng cách.
Nicklas Avén

1
Nik nói đúng, trong cả hình học và địa lý, hàm khoảng cách trả về khoảng cách giữa các cạnh. Ví dụ: chọn st_distance ('LINESTRING (0 0, 0 100)', 'LINESTRING (50 1, 51 1)')
Paul Ramsey

2
wow, cơ sở dữ liệu không gian làm đá! Tôi đang tính khoảng cách giữa một tập hợp ~ 8200 đa giác và hàng xóm gần nhất trong một tập hợp khác ~ 8400 đa giác. trong arcgis 10, công cụ 'tạo gần bảng' với bán kính tìm kiếm 10000 m mất 1 giờ 15 phút (trên máy tính để bàn i7 lõi ​​tứ 3,4 GHz). cùng một truy vấn trong PostGIS chỉ mất 3,5 phút và đó là trên một máy tính chậm hơn (macbook pro i7 lõi ​​kép 2,7 GHz).
quả hồ trăn

8

Khoảng cách từ A đến B giống như B đến A và khoảng cách từ A đến A bằng 0, do đó, một nửa ma trận sẽ giúp bạn tiết kiệm một số công việc.

IProighborOperator trả về khoảng cách từ cạnh. Mã dưới đây sử dụng phép chiếu phương vị tập trung vào tâm của mỗi đa giác (cũng nên hoạt động với các dòng). Nếu các đa giác không quá phức tạp (hoặc nếu bạn có nhiều bộ nhớ) thì việc tải tất cả các hình học vào bộ nhớ, việc chiếu chúng sẽ nhanh hơn. (Điều này không được kiểm tra kỹ lưỡng).

public class Pair
{
    public int Oid1;
    public int Oid2;
    public double Dist;
    public static void TestGetDistances()
    {
        IWorkspaceFactory wsf = new ESRI.ArcGIS.DataSourcesGDB.FileGDBWorkspaceFactoryClass();

        string path = @"C:\Program Files\ArcGIS\DeveloperKit10.0\Samples\data\Usa\USA.gdb";
        var fws = wsf.OpenFromFile(path, 0) as IFeatureWorkspace;
        IFeatureClass fc = fws.OpenFeatureClass("states");
        var halfMatrix = Pair.GetPairs(fc);

    }
    /// <summary>
    /// key is oid of each feature, value is pairs for features with smaller oids.
    /// </summary>
    /// <param name="fc"></param>
    /// <returns></returns>
    public static SortedList<int, List<Pair>> GetPairs(IFeatureClass fc)
    {
        ISpatialReferenceFactory3 srf = new SpatialReferenceEnvironmentClass();
        IProjectedCoordinateSystem pcs = 
        srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_WGS1984N_PoleAziEqui);

        var outList = new SortedList<int, List<Pair>>();
        IFeatureCursor fCur = fc.Search(null, true);
        IFeature f;
        while ((f = fCur.NextFeature()) != null)
        {
            var pairs = GetDistances(f, pcs);
            Debug.Print("{0} has {1} pairs", f.OID, pairs.Count);
            outList.Add(f.OID, pairs);
        }
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
        return outList;
    }

    private static IPoint GetGCSCentroid(IGeometry geom)
    {
        if (geom.SpatialReference is IProjectedCoordinateSystem)
        {
            geom.Project(((IProjectedCoordinateSystem)geom.SpatialReference).GeographicCoordinateSystem);
        }
        IArea a = geom is IArea ? geom as IArea : geom.Envelope as IArea;
        return a.Centroid;
    }

    /// <summary>
    /// return a list of all other features whose OID is lesser than f1
    /// </summary>
    /// <param name="f1"></param>
    /// <param name="pcs"></param>
    /// <returns></returns>
    private static List<Pair> GetDistances(IFeature f1, IProjectedCoordinateSystem pcs)
    {
        IPoint centroid = GetGCSCentroid(f1.ShapeCopy);

        pcs.set_CentralMeridian(true, centroid.X);
        ((IProjectedCoordinateSystem2)pcs).LatitudeOfOrigin = centroid.Y;
        var g1 = f1.ShapeCopy;
        g1.Project(pcs);

        var outList = new List<Pair>();
        var fc = f1.Class as IFeatureClass;
        var proxOp = g1 as IProximityOperator;
        IFeatureCursor fCur = fc.Search(null, true);
        IFeature f2 = null;
        while ((f2 = fCur.NextFeature()) != null)
        {
            if (f2.OID < f1.OID)
            {
                var g2 = f2.ShapeCopy;
                g2.Project(pcs);
                outList.Add(new Pair()
                {
                    Oid1 = f1.OID,
                    Oid2 = f2.OID,
                    Dist = proxOp.ReturnDistance(g2)
                });
            }
        }
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(fCur);
        return outList;
    }
}

đây là một đoạn mã hay Tôi không biết về IproighborOperator và cuối cùng tôi đã mã hóa thứ gì đó giống như thế này (rõ ràng là chậm hơn)
George Silva


2

Tôi nghĩ rằng công cụ gần bàn sẽ hoạt động cho những gì bạn muốn:

Xác định khoảng cách từ mỗi tính năng trong các tính năng đầu vào đến một hoặc nhiều tính năng gần đó trong các tính năng gần, trong bán kính tìm kiếm. Các kết quả được ghi lại trong bảng đầu ra.

Chỉ cần để trống bán kính tìm kiếm.


Đây là giải pháp tôi sẽ thử đầu tiên nhưng nó cần một mức cấp phép ArcInfo để mở khóa công cụ Tạo bảng gần (Phân tích).
PolyGeo
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.