आर्कगिस डेस्कटॉप का उपयोग करके बहुभुज की दूरी को न्यूनतम बढ़त मिल रही है?


9

मेरे पास आर्कगिस 10. में लगभग 3000 बहुभुजों का नक्शा है। मैं उनमें से प्रत्येक के बीच की दूरी का पता लगाना चाहता हूं। मुझे पता है कि इसे सेंट्रो के लाट और लंबे निर्देशांक का उपयोग कैसे करना है, लेकिन मैं एक बहुभुज के निकटतम किनारे से दूसरी बहुभुज के निकटतम किनारे तक सबसे छोटी सीधी रेखा की दूरी की तलाश कर रहा हूं। कोई विचार?

जवाबों:


11

यह कोड का एक अच्छा टुकड़ा है, लेकिन लगभग उतना अच्छा नहीं है (मान लें कि आपकी तालिका भौगोलिक निर्देशांक में है, अगर सिर्फ भूगोल के लिए कास्ट नहीं हटाएं)

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;

क्या मैंने उस स्थानिक डेटाबेस रॉक का उल्लेख किया है? वे करते हैं। ओह, वे करते हैं।


यह निकटतम कोने के बीच की दूरी को पा लेगा, लेकिन किनारों को खुद नहीं - ऐसा नहीं लगता है कि GEOS इस अधिक सटीक उत्तर को उजागर करता है। फिर भी, काफी आसान!
scw

1
सॉरी स्कव, आप कई मायनों में गलत हैं। PostGIS की मूल दूरी की गणना है। इसमें GOES शामिल नहीं है। दूसरा, यह पूरी तरह से किनारों के बीच निकटतम दूरी देता है, न केवल ज्यामिति दूरी और भूगोल प्रकार गोलाकार दूरी की गणना में दोनों कोने। पॉल ने इसे लिखा था।
निकलैस एवन

ज्यामिति के लिए इसे नेत्रहीन रूप से देखने के लिए आप st_shortestline का उपयोग कर सकते हैं जो उस दूरी को देने वाली रेखा को लौटाता है।
निकोलस एवन

1
निक सही है, ज्यामिति और भूगोल दोनों में दूरी फ़ंक्शन किनारों के बीच की दूरी को लौटाता है। उदाहरण के लिए, st_distance ('LINESTRING (0 0, 0 100)', 'LINESTRING (50 1, 51 1)') का चयन करें
पॉल रैमसे

2
वाह, स्थानिक डेटाबेस रॉक करते हैं! मैं ~ 8200 पॉलीगोन के एक सेट और ~ 8400 पॉलीगोन के दूसरे सेट में निकटतम पड़ोसी के बीच की दूरी की गणना कर रहा हूं। आर्कगिस 10 में, 10000 मीटर की खोज त्रिज्या के साथ 'जेनरेटिंग टेबल' के पास उपकरण 1 घंटा 15 मिनट (3.4 गीगाहर्ट्ज़ क्वाड-कोर आई 7 डेस्कटॉप पर) लिया गया। PostGIS में एक ही क्वेरी केवल 3.5 मिनट लेती है, और यह एक धीमे कंप्यूटर (2.7 गीगाहर्ट्ज़ डुअल-कोर i7 मैकबुक प्रो) पर थी।
पिस्ताचियोनट

8

A से B की दूरी B से A के समान है, और A से A की दूरी शून्य है, इसलिए आधा मैट्रिक्स आपको कुछ काम बचाएगा।

IPro निकटता से बढ़त से दूरी वापस आती है। नीचे दिया गया कोड प्रत्येक बहुभुज के केंद्रक पर केंद्रित अजीमुथल प्रक्षेपण का उपयोग करता है (लाइनों के साथ भी काम करना चाहिए)। यदि बहुभुज बहुत जटिल नहीं हैं (या यदि आपके पास बहुत अधिक मेमोरी है) तो सभी जियोमेट्री को मेमोरी में लोड करना एक प्रोजेक्टिंग है जो उन्हें तेजी से होगा। (यह अच्छी तरह से परीक्षण नहीं किया गया है)।

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;
    }
}

यह कोड का एक अच्छा टुकड़ा है। मैं Ipro निकटता के बारे में नहीं जानता था, और कुछ इस तरह से कोडिंग कर रहा था (जाहिर है यह धीमा है)
जॉर्ज सिल्वा


2

मुझे लगता है कि आप जो चाहते हैं उसके लिए पास टेबल टूल काम करेगा:

इनपुट सुविधाओं में प्रत्येक सुविधा से दूरी को एक या एक से अधिक पास की सुविधाओं में, निकट की विशेषताओं में, खोज त्रिज्या के भीतर निर्धारित करता है। परिणाम आउटपुट तालिका में दर्ज किए जाते हैं।

बस खोज त्रिज्या खाली छोड़ दें।


यह वह उपाय है जिसे मैं पहले करने की कोशिश करूंगा लेकिन इसे जनरेट नियर टेबल (एनालिसिस) टूल को अनलॉक करने के लिए ArcInfo लाइसेंस स्तर की आवश्यकता है।
PolyGeo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.