এসকিউএল সার্ভার - বৃহত্তর বহুভুজের মধ্যে নেস্টেড সমস্ত বহুভুজ নির্বাচন করুন


9

এটি একটি আপাতদৃষ্টিতে সহজ এসকিউএল সার্ভার জ্যামিতি প্রশ্ন যা আমি ভেবেছিলাম একটি বাক্সের বাইরে সমাধান হবে তবে আমার ভাগ্য ভাল নয় finding

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

আমার প্রয়োজন অনুযায়ী কাজ করা একটি বিকল্প বিকল্প ছিল STIntersection। এই ফাংশনটি নিয়ে সমস্যাটি হ'ল এটি কেবল জ্যামিতির কলামটি দেয়! পরিবর্তে আমি রেকর্ড আইডি পেতে চাই। এটি কীভাবে করা যায় সে সম্পর্কে কারও কি পরামর্শ আছে?

STWithin:

select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STWithin(b.shape) = 1
where b.mktname = 'Loop'

STContains:

select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on b.shape.STContains(a.shape) = 1
where b.mktname = 'Loop'

STIntersection:

select a.shape.STIntersection(b.shape)
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

সম্পাদনা:

একটি পরামর্শ হ'ল বাদ দেওয়া STIntersectionএবং কেবলমাত্র STIntersectsনিম্নরূপে ব্যবহার করা :

STIntersects:

select a.bg10
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

এই পদ্ধতির সমস্যাটি হ'ল এটি যে STIntersectsসমস্ত বহুভুজ নির্বাচন করে যা অভ্যন্তরে বা বাইরে রয়েছে এবং বৃহত্তর বহুভুজকে স্পর্শ করছে, কেবলমাত্র কঠোরভাবে নয়। উদাহরণস্বরূপ চিত্র দেখুন।STIntersects ফাংশন থেকে ফলাফল


আপনি আপনার বহুত্বপূর্ণ বহুভুজের উপর একটি ন্যূনতম বাফার করার চেষ্টা করতে পারেন এবং তারপরে STContainsঅথবা হয় ব্যবহার করতে পারেন STWithin। আসলেই খুব সুন্দর হ্যাক নয়, তবে আপনি যে ফলাফল চান তা পাবেন। অন্য বিকল্পটি হবে ছেদ ক্ষেত্র এবং বহুভুজের ক্ষেত্রের তুলনা করে STIntersects করা।
মিকিটি

আমি তুলনামূলকভাবে একটি অঞ্চলে কাজ শুরু করেছিলাম তবে জ্যামিতির সাথে তুলনামূলকভাবে জ্যামিতিকে কোনও সংখ্যায় ইত্যাদিতে রূপান্তর করার সাথে একটি খরগোশের গর্তে
উঠলাম

উত্তর:


8

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

SELECT a.bg10 
FROM gis.usa_10_block_group a
    JOIN gis.usa_10_mkt_definition b
        ON a.shape.STWithin(b.shape.STBuffer(0.0001)) = 1
WHERE b.mktname = 'Loop'

স্থানিক কয়েকটি পদ্ধতির প্রত্যাশিত আচরণের একটি দ্রুত উদাহরণ এখানে।

SELECT Geometry::STGeomFromText(WKT,0), Description
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STIntersects(Geometry::STGeomFromText(WKT,0)) Intersects
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STContains(Geometry::STGeomFromText(WKT,0)) Contained
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STOverlaps(Geometry::STGeomFromText(WKT,0)) Overlaps
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STTouches(Geometry::STGeomFromText(WKT,0)) Touches
FROM (VALUES
    ('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))'            ,'Interior corner')
    ,('POLYGON((90 90, 100 90, 100 100, 90 100, 90 90))' ,'Interior corner')
    ,('POLYGON((20 20, 40 20, 40 40, 20 40, 20 20))'     ,'Interior')
    ,('POLYGON((50 0, 70 0, 70 20, 50 20, 50 0))'        ,'Interior edge')
    ,('POLYGON((50 80, 70 80, 70 100, 50 100, 50 80))'   ,'Interior edge')
    ,('POLYGON((80 50, 100 50, 100 70, 80 70, 80 50))'   ,'Interior edge')
    ,('POLYGON((90 0, 110 0, 110 20, 90 20, 90 0))'      ,'Overlap')
    ,('POLYGON((100 50, 120 50, 120 70, 100 70, 100 50))','Exterior edge')
    )P(WKT,Description)
UNION ALL 
SELECT Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0),'Bounding Area',null,null,null,null

ফলাফল

Description     Intersects Contained Overlaps Touches
--------------- ---------- --------- -------- -------
Interior corner 1          1         0        0
Interior corner 1          1         0        0
Interior        1          1         0        0
Interior edge   1          1         0        0
Interior edge   1          1         0        0
Interior edge   1          1         0        0
Overlap         1          0         1        0
Exterior edge   1          0         0        1
Bounding Area   NULL       NULL      NULL     NULL

এটি দুর্দান্ত কাজ করে! আমাকে বাফার আকারটি 0.001 এ হ্রাস করতে হয়েছিল, তবে ধারণাটি কার্যকর হয়েছিল। আমি বিষয়টি সন্দেহ করছি যে gis.usa_10_mkt_definition টেবিলের জ্যামিতিগুলি gis.usa_10_ block_group হিসাবে একই টপোলজি থেকে উদ্ভূত নয়, কারণ আপনি যে প্রত্যাশিত ফলাফলটি উল্লেখ করেছেন তার থেকে কেন বিচ্যুত হয় তা ব্যাখ্যা করে। আমি দুটি টেবিল ব্যবহার করে একই টপোলজি ভাগ করে এসটিউইথিনের ব্যবহার পরীক্ষা করেছিলাম এবং কোনও বাফারের প্রয়োজন হয়নি।
ব্যবহারকারী 1185790

2

ছেদকৃত ক্যোয়ারীটি দেখতে এমন হওয়া উচিত (ধরে নিই যে আপনি সমস্ত রেকর্ড 'ক' থেকে ফিরে চান):

select a.* --get all columns from table 'a'
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

আপনি যদি কেবল ছেদকৃত খের (যেমন, একটিতে বি ক্লিপিংয়ের) ক্ষেত্রগুলি চান তবে আপনি STIntersction যুক্ত করুন

select a.bg10
, a.STIntersection(b.geom) --clipped geometry from a against b
    from gis.usa_10_block_group a
    join gis.usa_10_mkt_definition b
    on a.shape.STIntersects(b.shape) = 1
    where b.mktname = 'Loop'

তবে এটি আপনাকে এখনও বহুভুজগুলি পায় না যা খ এর মধ্যে রয়েছে ...

এই ধরণের বহুভুজ-ইন-বহুভুজটি সীমানা এবং তাদের কন্সিস্টেন্সের সাথে খুব টেস্টি - এটি 'এর মধ্যে' হওয়ার জন্য, এর গণ্ডি খ-এর সীমানার সাথে সঙ্গতিপূর্ণ হতে পারে না same একইভাবে এটি ধারণ করে for

এই সংজ্ঞা দ্বারা, একটি কিভাবে আপনার বহুভুজের অনেক আসলে খ মধ্যে ...?

সুতরাং আপনি কি এর মধ্যে একটি বহুভুজ নির্বাচন করার আগে বি বাফার করতে চান? বা একটি নেতিবাচক বাফার করবেন?

সঠিক উত্তর এখানে কি তা নিশ্চিত নন ...


সম্পূর্ণরূপে ব্যাখ্যা করার জন্য সম্পাদনা দেখুন কেন আমি এর পরে ঠিক তাই হয় না
ব্যবহারকারীর 1185790

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