আর্কজিআইএস ডেস্কটপ ব্যবহার করে বহুভুজের দূরত্বের সর্বনিম্ন প্রান্তটি সন্ধান করছেন?


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;

আমি কি স্থানিক ডাটাবেস রক উল্লেখ করেছি? তারা করে. ওহ, তারা না।


এটি নিকটতম কোণগুলির মধ্যে দূরত্বটি খুঁজে পাবে, তবে কিনারা নিজেরাই নয় - মনে হয় না যে জিইওএস এই আরও সুনির্দিষ্ট উত্তরটি প্রকাশ করে। তবুও বেশ সহজ!
স্কু

1
দুঃখিত স্ক্রু, আপনি অনেক উপায়ে ভুল। পোস্টজিআইএসের দেশীয় দূরত্বের গণনা রয়েছে। GOES এতে জড়িত নয়। দ্বিতীয়ত, এটি পুরোপুরি প্রান্তগুলির মধ্যে নিকটতম দূরত্ব দেয়, জ্যামিতির দূরত্ব এবং ভূগোলের ধরণের স্পেরয়েড দূরত্ব গণনা উভয়কেই উল্লম্ব করে না। পল এটি লিখেছিলেন।
নিক্লাস অ্যাভেন

জ্যামিতির জন্য এটি দেখার জন্য আপনি st_shortestline ব্যবহার করতে পারেন যা লাইনটি দেয় যা দূরত্ব দেয়।
নিক্লাস অ্যাভন

1
নিক ঠিক বলেছেন, জ্যামিতি এবং ভূগোল উভয় ক্ষেত্রেই দূরত্ব ফাংশনটি প্রান্তগুলির মধ্যে দূরত্ব ফিরিয়ে দেয়। উদাহরণস্বরূপ, st_distance নির্বাচন করুন ('লাইনস্ট্রিং (0 0, 0 100)', 'লাইনস্ট্রিং (50 1, 51 1)')
পল রামসে

2
বাহ, স্থানিক ডাটাবেস রক না! আমি 00 8200 বহুভুজের সেট এবং নিকটতম প্রতিবেশী another 8400 বহুভুজের আরও একটি সেট এর মধ্যে দূরত্ব গণনা করছি। আরকিগিস 10-এ, 10000 মিটার অনুসন্ধানের ব্যাসার্ধের সাথে 'টেবিল জেনারেট টেবিল' সরঞ্জামটি 1 ঘন্টা এবং 15 মিনিট সময় নেয় (3.4 গিগাহার্টজ কোয়াড-কোর আই 7 ডেস্কটপে)। পোস্টজিআইএস-এ একই ক্যোয়ারীটি কেবলমাত্র 3.5 মিনিট সময় নিয়েছিল এবং এটি একটি ধীর কম্পিউটারে ছিল (একটি 2.7 গিগাহার্টজ ডুয়াল-কোর আই 7 ম্যাকবুক প্রো)।
পিস্তুনাট

8

A থেকে B এর দূরত্ব B থেকে A এর সমান এবং A থেকে A এর দূরত্ব শূন্য, অতএব অর্ধ ম্যাট্রিক্স আপনাকে কিছু কাজ বাঁচাবে।

IProximityOperator প্রান্ত থেকে দূরত্ব ফিরিয়ে দেয়। নীচের কোডটিতে প্রতিটি বহুভুজের সেন্ট্রয়েডকে কেন্দ্র করে একটি আজিমুথাল প্রক্ষেপণ ব্যবহার করা হয় (লাইনগুলির সাথেও কাজ করা উচিত)। বহুভুজ যদি খুব জটিল না হয় (বা যদি আপনার প্রচুর স্মৃতি থাকে) সমস্ত জ্যামিতিগুলিকে মেমোরিতে লোড করা হয় তবে তাদের একটি প্রজেক্টিং দ্রুততর হবে। (এটি পুরোপুরি পরীক্ষা করা হয় না)।

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

এটি একটি চমৎকার কোড। আমি আইপ্রক্সিমিটি অপারেটর সম্পর্কে জানতাম না, এবং নিজেই কিছুটা এরকম কোডিং শেষ করলাম (স্পষ্টতই এটি ধীর)
জর্জ সিলভা

3

গণনাটি এমন কিছু নয় যা আর্কজিআইএস স্থানীয়ভাবে সরবরাহ করে তবে আমি আকারে সমস্যার সমাধান দিয়েছি যা সাহায্য করতে পারে বা পুরানো আরকজিআইএস ফোরামে এই থ্রেডটি দেয়।


2

আমি মনে করি কাছের টেবিল সরঞ্জামটি আপনি যা চান তার জন্য কাজ করবে:

অনুসন্ধান ব্যাসার্ধের মধ্যে, ইনপুট বৈশিষ্ট্যগুলির প্রতিটি বৈশিষ্ট্য থেকে নিকটবর্তী বৈশিষ্ট্যগুলিতে এক বা একাধিক বৈশিষ্ট্যগুলিতে দূরত্ব নির্ধারণ করে। ফলাফল আউটপুট সারণীতে রেকর্ড করা হয়।

কেবল অনুসন্ধান ব্যাসার্ধকে ফাঁকা ছেড়ে দিন।


এটিই সমাধানটি আমি প্রথমে চেষ্টা করব তবে জেনারেট নের টেবিল (বিশ্লেষণ) সরঞ্জামটি আনলক করার জন্য এটির জন্য একটি আর্কইনফো লাইসেন্স স্তর প্রয়োজন।
পলিজিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.