SQL सर्वर - एक बड़े बहुभुज के भीतर नेस्टेड सभी बहुभुज का चयन करें


9

यह एक प्रतीत होता है सरल SQL सर्वर ज्योमेट्री प्रश्न है कि मुझे लगा कि इसका आउट-ऑफ-द-बॉक्स समाधान होगा, लेकिन मुझे एक भी भाग्य नहीं मिल रहा है।

मेरा इरादा एक मेज के भीतर सभी रिकॉर्ड का चयन करना है जिसमें बहुभुज हैं जो दूसरे टेबल से बड़े बहुभुज के भीतर नेस्टेड (निहित) हैं। मेरे पास अपेक्षित कार्य थे 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। वास्तव में एक अच्छा हैक नहीं है, लेकिन आपको मनचाहा परिणाम मिलेगा। दूसरा विकल्प यह होगा कि STIntersect को Intersection क्षेत्र और बहुभुज क्षेत्र की तुलना के साथ किया जाए।
मिकी

मैंने एक क्षेत्र की तुलना पर काम करना शुरू कर दिया, लेकिन एक खरगोश छेद में मिला, जिसकी तुलना ज्यामिति से एक संख्या, आदि में क्षेत्र में परिवर्तित हो गई ...
DPSSpatial

जवाबों:


8

सिद्धांत रूप में आपके द्वारा किए गए प्रश्नों को आपके द्वारा दिए गए बहुभुजों को वापस कर देना चाहिए। इससे मुझे संदेह है कि आप अस्थायी बिंदु त्रुटि समस्याओं का सामना कर सकते हैं जो SQL सर्वर ने स्थानिक डेटा प्रकारों के साथ किया है। इसलिए न्यूनतम राशि के साथ बाउंडिंग बहुभुज को बफर करने के बारे में मेरी टिप्पणी।
तो निम्नलिखित की तरह कुछ आप चाहते हैं परिणाम प्राप्त करना चाहिए।

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 के समान टोपोलॉजी से व्युत्पन्न नहीं हैं, इसका कारण बताते हुए कि यह उस अपेक्षित परिणाम से उत्पन्न होता है जिसका आपने उल्लेख किया था। मैंने STWithin के दो तालिकाओं का उपयोग करके परीक्षण किया जो एक ही टोपोलॉजी को साझा करते हैं, और किसी बफर की आवश्यकता नहीं थी।
15:11 बजे user1185790

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'

यदि आप उस प्रतिच्छेदन b के क्षेत्र (यानी क्लिपिंग टू b) चाहते हैं, तो आप STIntersection जोड़ें

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'

लेकिन यह आपको बहुभुज नहीं मिलता है जो अभी तक बी के भीतर हैं ...

इस प्रकार के बहुभुज-इन-बहुभुज की सीमाओं और उनके संयोग के साथ बहुत ही टेस्टी है - 'भीतर' होने के लिए, ब की सीमाओं के साथ विश्वास नहीं किया जा सकता है - वही 'कंटेन्स' के लिए जाता है।

इन परिभाषाओं के द्वारा, वास्तव में b में आपके कितने बहुभुज हैं ...?

तो क्या आप बहुभुज का चयन करने से पहले b को बफर करना चाहते हैं? या पर एक नकारात्मक बफर करते हैं?

निश्चित नहीं है कि यहाँ सटीक उत्तर क्या है ...


पूर्ण स्पष्टीकरण के लिए संपादन देखें कि यह काफी नहीं है क्योंकि मैं इसके बाद हूँ
user1185790

मैं देखता हूं कि आप क्या करने की कोशिश कर रहे हैं ... अब कुछ काम कर रहे हैं ...
DPSSpatial
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.