পোস্টজিআইএস-এ ভোরোনাই চিত্রটি নির্মাণ করা


12

আমি থেকে পরিবর্তিত কোড ব্যবহার পয়েন্ট গ্রিড থেকে voronoi ডায়াগ্রাম গঠন করা চেষ্টা করছি এখানে । এটি আমার পরিবর্তনের পরে এসকিউএল কোয়েরি:

DROP TABLE IF EXISTS example.voronoi;
WITH 
    -- Sample set of points to work with
    Sample AS (SELECT ST_SetSRID(ST_Union(geom), 0) geom FROM example."MeshPoints2d"),
    -- Build edges and circumscribe points to generate a centroid
    Edges AS (
    SELECT id,
        UNNEST(ARRAY['e1','e2','e3']) EdgeName,
        UNNEST(ARRAY[
            ST_MakeLine(p1,p2) ,
            ST_MakeLine(p2,p3) ,
            ST_MakeLine(p3,p1)]) Edge,
        ST_Centroid(ST_ConvexHull(ST_Union(-- Done this way due to issues I had with LineToCurve
            ST_CurveToLine(REPLACE(ST_AsText(ST_LineMerge(ST_Union(ST_MakeLine(p1,p2),ST_MakeLine(p2,p3)))),'LINE','CIRCULAR'),15),
            ST_CurveToLine(REPLACE(ST_AsText(ST_LineMerge(ST_Union(ST_MakeLine(p2,p3),ST_MakeLine(p3,p1)))),'LINE','CIRCULAR'),15)
        ))) ct      
    FROM    (
        -- Decompose to points
        SELECT id,
            ST_PointN(g,1) p1,
            ST_PointN(g,2) p2,
            ST_PointN(g,3) p3
        FROM    (
            SELECT (gd).Path id, ST_ExteriorRing((gd).geom) g -- ID andmake triangle a linestring
            FROM (SELECT (ST_Dump(ST_DelaunayTriangles(geom))) gd FROM Sample) a -- Get Delaunay Triangles
            )b
        ) c
    )
SELECT ST_SetSRID((ST_Dump(ST_Polygonize(ST_Node(ST_LineMerge(ST_Union(v, ST_ExteriorRing(ST_ConvexHull(v)))))))).geom, 2180)
INTO example.voronoi
FROM (
    SELECT  -- Create voronoi edges and reduce to a multilinestring
        ST_LineMerge(ST_Union(ST_MakeLine(
        x.ct,
        CASE 
        WHEN y.id IS NULL THEN
            CASE WHEN ST_Within(
                x.ct,
                (SELECT ST_ConvexHull(geom) FROM sample)) THEN -- Don't draw lines back towards the original set
                -- Project line out twice the distance from convex hull
                ST_MakePoint(ST_X(x.ct) + ((ST_X(ST_Centroid(x.edge)) - ST_X(x.ct)) * 2),ST_Y(x.ct) + ((ST_Y(ST_Centroid(x.edge)) - ST_Y(x.ct)) * 2))
            END
        ELSE 
            y.ct
        END
        ))) v
    FROM    Edges x 
        LEFT OUTER JOIN -- Self Join based on edges
        Edges y ON x.id <> y.id AND ST_Equals(x.edge,y.edge)
    ) z

নীচে - আমার প্রশ্নের ফলাফল। এখানে চিত্র বর্ণনা লিখুন

আপনি দেখতে পাচ্ছেন যে অনন্য বহুভুজ নেই এমন হাইলাইট পয়েন্টগুলি বাদে আমি "প্রায়" সঠিক ভোরোনাই চিত্র পেয়েছি get নীচে কিউজিআইএস অ্যালগরিদম উত্পাদন করে এবং আমি কোয়েরি থেকে কী পেতে চাই। আমার কোড নিয়ে সমস্যা কোথায়?

এখানে চিত্র বর্ণনা লিখুন


সম্ভবত আপনি স্প্যাটিয়ালিট ফাংশন "ভোরোনোজডিয়াগ্রাম" গাইয়া- gis.it/gaia-sins/spatialite-sql-latest.html এর ফলাফলের সাথে তুলনা করতে পারেন এবং গাইয়া- gis.it/fossil/libspatialite/ এ উত্স কোডটি দেখতে পারেন সূচক
ব্যবহারকারী 30184

সুন্দর প্রশ্ন, আমি আপনার উল্লেখ করা একই প্রশ্নটির দিকে নজর দিচ্ছি, এটির গতি বাড়ানোর দৃষ্টিভঙ্গিতে, তবে সময়ের বাইরে দৌড়তে থাকুন। বাহ্যিক বিষয়গুলি নিয়ে আমি এই বিষয়টি সম্পর্কে সচেতন ছিলাম না।
জন পাওয়েল

5
পোস্ট গিস ২.৩. এ এস-ভারোণোই আসার জন্য আমাদের কী মূল্য আছে, ড্যান ব্যাস্টন শীঘ্রই এর জন্য কোডটি পরীক্ষা করে দেখবে - trac.osgeo.org/postgis/ticket/2259 দেখে মনে হচ্ছে এটিকে টানতে খুব দরকার হয়েছে to লোকেরা পরীক্ষা করছেন
LR1234567

আপনি যে পয়েন্টগুলি ব্যবহার করছেন সেগুলির সেট আপ পোস্ট করতে পারেন? আমি নিজে নিজে এই বিষয়ে কিছুটা পরীক্ষা করে
নেওয়ার বিষয়ে মনে

@ মিকিটি এখানে আমার ডেটার লিঙ্ক link ডেটা এসআরআইডি হ'ল 2180
ড্যামনব্যাক

উত্তর:


6

যদিও এটি প্রশ্নে থাকা ডেটার জন্য ক্যোয়ারী সহ তাত্ক্ষণিক সমস্যার সমাধান করে, সাধারণ ব্যবহারের সমাধান হিসাবে আমি এতে সন্তুষ্ট নই এবং আমি যখন পারব তখন আমি এই এবং পূর্ববর্তী উত্তরে পুনর্বিবেচনা করব।

সমস্যাটি হ'ল মূল ক্যোরিটি ভোরোনাই বহুভুজের বাহ্যিক প্রান্ত নির্ধারণ করতে ভোরোনাই প্রান্তগুলিতে উত্তল হাল ব্যবহার করছিল। এর অর্থ হ'ল কিছু ভোরোনাই প্রান্ত বহির্মুখী পৌঁছে না যখন তারা হওয়া উচিত ছিল। আমি অবতল হলের কার্যকারিতাটি ব্যবহার করে দেখলাম, তবে এটি আমার ইচ্ছা মতো কার্যকর হয়নি।
দ্রুত স্থির হিসাবে আমি ভোরোনাই প্রান্তের বদ্ধ সেট এবং মূল প্রান্তগুলির চারপাশে একটি বাফার তৈরি করার জন্য উত্তল হাল তৈরি করেছি। যে ভোরোনাই প্রান্তগুলি বন্ধ হয় না সেগুলি চেষ্টা করে এবং বাহ্যকে ছেদ করে এবং বহুভুজ তৈরিতে ব্যবহার হয় তা নিশ্চিত করার জন্য এটি একটি বিশাল দূরত্ব বাড়ানো হয়। আপনি বাফার প্যারামিটারগুলির সাথে প্রায় খেলতে চাইতে পারেন।

WITH 
    -- Sample set of points to work with
    Sample AS (SELECT ST_SetSRID(ST_Union(geom), 0) geom FROM MeshPoints2d),
    -- Build edges and circumscribe points to generate a centroid
    Edges AS (
    SELECT id,
        UNNEST(ARRAY['e1','e2','e3']) EdgeName,
        UNNEST(ARRAY[
            ST_MakeLine(p1,p2) ,
            ST_MakeLine(p2,p3) ,
            ST_MakeLine(p3,p1)]) Edge,
        ST_Centroid(ST_ConvexHull(ST_Union(-- Done this way due to issues I had with LineToCurve
            ST_CurveToLine(REPLACE(ST_AsText(ST_LineMerge(ST_Union(ST_MakeLine(p1,p2),ST_MakeLine(p2,p3)))),'LINE','CIRCULAR'),15),
            ST_CurveToLine(REPLACE(ST_AsText(ST_LineMerge(ST_Union(ST_MakeLine(p2,p3),ST_MakeLine(p3,p1)))),'LINE','CIRCULAR'),15)
        ))) ct      
    FROM    (
        -- Decompose to points
        SELECT id,
            ST_PointN(g,1) p1,
            ST_PointN(g,2) p2,
            ST_PointN(g,3) p3
        FROM    (
            SELECT (gd).Path id, ST_ExteriorRing((gd).geom) g -- ID andmake triangle a linestring
            FROM (SELECT (ST_Dump(ST_DelaunayTriangles(geom))) gd FROM Sample) a -- Get Delaunay Triangles
            )b
        ) c
    )
SELECT ST_SetSRID((ST_Dump(ST_Polygonize(ST_Node(ST_LineMerge(ST_Union(v, (SELECT ST_ExteriorRing(ST_ConvexHull(ST_Union(ST_Union(ST_Buffer(edge,20),ct)))) FROM Edges))))))).geom, 2180) geom
INTO voronoi
FROM (
    SELECT  -- Create voronoi edges and reduce to a multilinestring
        ST_LineMerge(ST_Union(ST_MakeLine(
        x.ct,
        CASE 
        WHEN y.id IS NULL THEN
            CASE WHEN ST_Within(
                x.ct,
                (SELECT ST_ConvexHull(geom) FROM sample)) THEN -- Don't draw lines back towards the original set
                -- Project line out twice the distance from convex hull
                ST_MakePoint(ST_X(x.ct) + ((ST_X(ST_Centroid(x.edge)) - ST_X(x.ct)) * 200),ST_Y(x.ct) + ((ST_Y(ST_Centroid(x.edge)) - ST_Y(x.ct)) * 200))
            END
        ELSE 
            y.ct
        END
        ))) v
    FROM    Edges x 
        LEFT OUTER JOIN -- Self Join based on edges
        Edges y ON x.id <> y.id AND ST_Equals(x.edge,y.edge)
    ) z;

সমস্যার সমাধান এবং দ্রুত সমাধানের জন্য ধন্যবাদ! এটি আমার ডেটা (কিছুটা ধীরে ধীরে ধীর হয়ে ST_Union(ST_Buffer(geom))) এর সাথে কাজ করে তবে আমি পয়েন্টের অন্যান্য সেটগুলির সাথে পরীক্ষা চালিয়ে যাব। ইতিমধ্যে আপনি যেমনটি বলেছেন তার জন্য আমি অপেক্ষা করব - আরও সাধারণ সমাধান। :)
ড্যামনব্যাক

আপনার চূড়ান্ত আউটপুটে পোস্ট করতে পারেন এমন কোনও চিত্র আছে কি?
জেরিল কুক

10

@Dbaston দ্বারা বিকাশ করা নতুন ST_Voronoi কার্যকারিতা চেষ্টা করার জন্য @ LR1234567 এর পরামর্শ অনুসরণ করে, @ মিকিটির মূল আশ্চর্যজনক উত্তর (ওপির প্রশ্নে বর্ণিত) এবং আসল ডেটা ব্যবহার করে এখন এটিকে সহজ করা যেতে পারে:

WITH voronoi (vor) AS 
     (SELECT ST_Dump(ST_Voronoi(ST_Collect(geom))) FROM meshpoints)
SELECT (vor).path, (vor).geom FROM voronoi;

এই ফলাফলটি ওপি-র প্রশ্নের অনুরূপ output

এখানে চিত্র বর্ণনা লিখুন

যাইহোক, এটি একই সমস্যার সাথে ভুগছে, এটি এখন মিকিটির উত্তরে স্থির হয়েছে, অবতল হলের উপরের পয়েন্টগুলি একটি সংলগ্ন বহুভুজ পায় না (যেমনটি অ্যালগোরিদম থেকে প্রত্যাশিত হবে)। নিম্নলিখিত পদক্ষেপের ক্রিয়াকলাপের সাথে আমি এই সমস্যাটি সমাধান করেছি।

  1. ইনপুট পয়েন্টগুলির অবতল হলের গণনা করুন - অবতল হলের পয়েন্টগুলি হ'ল আউটপুট ভোরোনাই ডায়াগ্রামে আনবাউন্ডেড বহুভুজ রয়েছে।
  2. অবতল হলের মূল পয়েন্টগুলি সন্ধান করুন (নীচের চিত্রের 2 টিতে হলুদ পয়েন্ট)।
  3. অবতল হলের বাফার করুন (বাফার দূরত্বটি নির্বিচারে এবং সম্ভবত ইনপুট ডেটা থেকে আরও অনুকূলভাবে পাওয়া যাবে?)
  4. দ্বিতীয় ধাপে পয়েন্টের নিকটে অবতল হলের বাফারে নিকটতম পয়েন্টগুলি সন্ধান করুন এটি নীচের চিত্রের মধ্যে সবুজ হিসাবে দেখানো হয়েছে।
  5. মূল তথ্য সেট এ এই পয়েন্টগুলি যুক্ত করুন
  6. এই সম্মিলিত ডেটা সেটের ভোরোনাই চিত্রটি গণনা করুন। তৃতীয় চিত্রটিতে যেমন দেখা যায়, হলের উপরের পয়েন্টগুলিতে এখন বহুভুজগুলি ঘের রয়েছে।

ডায়াগ্রাম 2 অবতল হোল (হলুদ) এবং পশুর উপর বাফার নিকটতম পয়েন্টগুলি (সবুজ) দেখায় points চিত্র 2।

কোয়েরিটি স্পষ্টতই সরল / সংকুচিত হতে পারে তবে আমি এই ফর্মটি সিটিইগুলির একটি সিরিজ হিসাবে রেখেছি কারণ ধারাবাহিকভাবে সেই পদক্ষেপগুলি অনুসরণ করা আরও সহজ। এই কোয়েরিটি মিলি সেকেন্ডে 11 ​​ডিগ্রি গড়ে (একটি ডেভ সার্ভারে গড়ে 11 মিমি) ডেটা সেট করে তবে মিক্যটির উত্তর একই সার্ভারে 4800 মিমি তে ST_Delauney ব্যবহার করে। ডি ব্যাস্টন দাবি করেছেন যে ত্রিভুজ কর্মের রুটিন বৃদ্ধির কারণে জিইওএসের বর্তমান ট্রাঙ্ক, ৩.6 ডিভের বিপরীতে বিল্ডিং থেকে আরও বাড়ানো গতি বাড়ানোর আর একটি অর্ডার পাওয়া যেতে পারে।

WITH 
  conv_hull(geom) AS 
        (SELECT ST_Concavehull(ST_Union(geom), 1) FROM meshpoints), 
  edge_points(points) AS 
        (SELECT mp.geom FROM meshpoints mp, conv_hull ch 
        WHERE ST_Touches(ch.geom, mp.geom)), 
  buffered_points(geom) AS
        (SELECT ST_Buffer(geom, 100) as geom FROM conv_hull),
  closest_points(points) AS
        (SELECT 
              ST_Closestpoint(
                   ST_Exteriorring(bp.geom), ep.points) as points,
             ep.points as epoints 
         FROM buffered_points bp, edge_points ep),
  combined_points(points) AS
        (SELECT points FROM closest_points 
        UNION SELECT geom FROM meshpoints),
  voronoi (vor) AS 
       (SELECT 
            ST_Dump(
                  ST_Voronoi(
                    ST_Collect(points))) as geom 
        FROM combined_points)
 SELECT 
     (vor).path[1] as id, 
     (vor).geom 
 FROM voronoi;

চিত্র 3 সমস্ত পয়েন্ট দেখাচ্ছে এখন বহুভুজের মধ্যে আবদ্ধ চিত্র 3

দ্রষ্টব্য: বর্তমানে ST_Voronoi এর উত্স থেকে পোস্টগিস তৈরি করা (সংস্করণ 2.3, বা ট্রাঙ্ক) এবং জিইওএস 3.5 বা তদুর্ধের সাথে লিঙ্ক করা জড়িত।

সম্পাদনা: আমি স্রেফ পোস্টগিস ২.৩ এ দেখেছি যেহেতু এটি অ্যামাজন ওয়েব পরিষেবাদিতে ইনস্টল করা আছে এবং মনে হয় ফাংশনটির নামটি এখন এসT_ ভারনোইপলিগনস।

সন্দেহ নেই এই কোয়েরি / অ্যালগোরিদম উন্নত হতে পারে। পরামর্শ স্বাগত জানাই।


@dbaston। এই পদ্ধতির বিষয়ে আপনার কোনও মন্তব্য থাকলে অবাক হচ্ছেন?
জন পাওয়েল

1
ভাল, পয়েন্ট সব না একটি অন্তর্নিহিত বহুভুজ পেতে, এটা ঠিক যে এটা সামঞ্জস্যহীনভাবে বড় মনে হবে। কীভাবে এবং কীভাবে এগুলি আরও ছোট করা উচিত তা যথেষ্ট বিষয়গত এবং বাইরের বহুভুজগুলির জন্য কী কী পছন্দ করা হয়েছে তা না জেনে "সেরা" উপায়টি কী তা জানা শক্ত। আপনার আমার কাছে একটি দুর্দান্ত পদ্ধতি মনে হচ্ছে। আমি আপনার সাথে আত্মার অনুরূপ একটি কম পরিশীলিত পদ্ধতি ব্যবহার করেছি, গড় পয়েন্ট ঘনত্ব দ্বারা নির্ধারিত একটি নির্দিষ্ট ব্যবধানে একটি বাফার উত্তল হাল সীমানা বরাবর অতিরিক্ত পয়েন্টগুলি ফেলে।
ডাবস্টন

@dbaston। ধন্যবাদ, কেবল নিশ্চিত করেই আমি স্পষ্ট কিছু মিস করছি না। আভ্যন্তরীণ আকারের আকারের সাথে বাইরের বহুভুজগুলিকে আরও কিছু সংকুচিত করার জন্য একটি অ্যালগরিদম (আমার ক্ষেত্রে পোস্টকোড অঞ্চলে) এমন কিছু যা আমি সম্পর্কে আরও ভাবতে হবে।
জন পাওয়েল

@ জন বারিয়া আরও একটি দুর্দান্ত সমাধানের জন্য ধন্যবাদ। গণনার গতি এই পদ্ধতির সাথে সন্তুষ্টির চেয়ে বেশি। দুর্ভাগ্যক্রমে আমি আমার QGIS প্লাগইনের ভিতরে এই অ্যালগরিদমটি ব্যবহার করতে চাই এবং এটি পোস্টজিআইএস ২.১++ এর বাইরে কাজ করতে হবে। তবে অবশ্যই পোস্টজিআইএস ২.৩ সরকারী প্রকাশের পরে আমি এই সমাধানটি ব্যবহার করব। যাইহোক এই জাতীয় উত্তরের জন্য আপনাকে ধন্যবাদ। :)
ড্যামনব্যাক

@DamnBack। তোমাকে সুস্বাগতম. কাজের জন্য আমার এটির প্রয়োজন ছিল এবং আপনার প্রশ্নটি আসলে আমাকে অনেক সাহায্য করেছিল, কারণ এস এস ভারোণোই বেরিয়ে আসার বিষয়ে আমার কোনও ধারণা ছিল না এবং পুরানো সমাধানগুলি অনেক ধীর (যেমন আপনি লক্ষ্য করেছেন)। এটি খুব মজার ছিল :-)
জন পাওয়েল

3

আপনার যদি পোস্টজিআইএস ২.৩ এ অ্যাক্সেস থাকে তবে নতুন এসT_ ভারোনোই ফাংশনটি একবার ব্যবহার করে দেখুন, প্রতিশ্রুতিবদ্ধ:

http://postgis.net/docs/manual-dev/ST_Voronoi.html

উইন্ডোজের জন্য পূর্বনির্ধারিত বিল্ডগুলি রয়েছে - http://postgis.net/windows_downloads/


তথ্যের জন্য ধন্যবাদ যে অন্তর্নির্মিত অন্তর্নির্মিত ST_Voronoi ফাংশন রয়েছে - আমি এটি পরীক্ষা করে দেখব। দুর্ভাগ্যক্রমে আমার এমন সমাধান দরকার যা পোস্টজিআইএস ২.১++ সংস্করণগুলিতে কাজ করে, সুতরাং @ মিকিটি ক্যোয়ারী এই মুহুর্তে আমার প্রয়োজনগুলির সবচেয়ে নিকটতম।
ড্যামনব্যাক

@ LR1234567। এর জন্য কি জিওওএসের কোনও বিশেষ সংস্করণ প্রয়োজন? আমার আগামীকাল ২.৩ এবং এসT_ ভারনোই পরীক্ষার জন্য সময় আছে।
জন পাওয়েল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.