2016-07-05 186 views
0

我有一種情況,我想要加載位於用戶視口內的地圖對象。DbGeography - 選擇包含在多邊形內的多邊形/線串

這是我如何創建用戶視口矩形:

DbGeography viewport_rectangle = DbGeography.FromText(string.Format("POLYGON(({0} {1}, {0} {2}, {3} {2}, {3} {1}, {0} {1}))", lon_min, lat_min, lat_max, lon_max)); 

然後我想選擇所有對象(點,折線,多邊形,位於矩形的內部):

var objects = db.mapobjects.Where(x => !x.LocationGeographic.Intersects(viewport_rectangle)); 

一切,直到這裏工作正常。如果PolyLine/Polygon沒有完全包含在視口多邊形中,問題就出現了。在這種情況下,它被忽略,我得到「沒有物體」而不是物體,其中一些點/邊緣不在視口中。

有沒有其他選擇「相交」?我想選擇視口矩形中包含的對象,而不管它們是否在裏面,或者只有一小部分位於視口矩形內。

viewport_rectangle = {SRID = 4326; POLYGON((15.693584159016611 46.532346466357438,15.693584159016611 46.532770863495614,15.695530101656916 46.532770863495614,15.695530101656916 46.532346466357438,15.693584159016611 46.532346466357438))}

對象,其僅部分地位於內部viewport_rectangle和應作爲結果返回:

LINESTRING(15.694189164787527 46.532622094224166,15.694309193640944 46.532614944062828,15.694392677396532 46.5326121762582,15.694401059299702 46.532662919320614,15.694536175578829 46.532621632923423,15.694564338773485 46.532659690218026,15.694584455341097 46.532614944062828,15.694570373743769 46.532578039989573,15.694489236921068 46.53258611275777,15.694502312690016 46.532539290685662,15.694723930209872 46.53252614359414,15.69474438205361 46.532575041532539,15.694786962121723 46.532516225610692,15.694763492792843 46.532481858630774,15.694699790328738 46.532507922181281,15.694884862750767 46.532493852478581,15.694849658757446 46.53254505695287)

一個LINQ的一部分生成的查詢:

選擇 [Filter1]。[ObjectId] AS [ObjectId], [Filter1]。[LocationGeographic] AS [LocationGeographic], FROM(SELECT [Extent1]。[ObjectId] AS [ObjectId],[Extent1]。[LocationGeographic ] AS [LocationGeographic] FROM [DBO]。[MapObjects的] AS [Extent1] WHERE(([過濾器1] [LocationGeographic] .STIntersects(@ p__linq__0))<>鑄件(1 作爲比特)) )AS [ PROJECT1]

編輯: viewport_rectangle的正確順序應該是:

DbGeography viewport_rectangle = DbGeography.FromText(string.Format("POLYGON(({0} {1}, {2} {1}, {2} {3}, {0} {3}, {0} {1}))", lon_min, lat_min, lon_max, lat_max)); 
+0

相交應該這樣做(假設它在DB端實現'STIntersects()')。您能否提供展示您建議的行爲的數據?一些傳遞給數據庫的內容也會有幫助。 –

+0

剛剛添加到基本問題。希望它能幫助你確定行爲的原因。 – Tadej

回答

1

您的多邊形似乎存在環形方向問題。您指定要點的順序很重要。正如你所定義的那樣,多邊形是整個地球減去一個非常小的正方形(大概是你想要的視口)。我是如何確定這一點的?

declare @line geography = geography::STGeomFromText('LINESTRING (15.694189164787527 46.532622094224166, 15.694309193640944 46.532614944062828, 15.694392677396532 46.5326121762582, 15.694401059299702 46.532662919320614, 15.694536175578829 46.532621632923423, 15.694564338773485 46.532659690218026, 15.694584455341097 46.532614944062828, 15.694570373743769 46.532578039989573, 15.694489236921068 46.53258611275777, 15.694502312690016 46.532539290685662, 15.694723930209872 46.53252614359414, 15.69474438205361 46.532575041532539, 15.694786962121723 46.532516225610692, 15.694763492792843 46.532481858630774, 15.694699790328738 46.532507922181281, 15.694884862750767 46.532493852478581, 15.694849658757446 46.53254505695287)', 4236), 
    @poly geography = geography::STGeomFromText('POLYGON ((15.693584159016611 46.532346466357438, 15.693584159016611 46.532770863495614, 15.695530101656916 46.532770863495614, 15.695530101656916 46.532346466357438, 15.693584159016611 46.532346466357438))', 4236); 

select @poly.EnvelopeAngle(); --returns 180 
select @poly.ReorientObject().STIntersects(@line); --returns 1 

最好你自己閱讀EnvelopeAngle()方法。但是我會說這個 - 我用它作爲快速啓發式來檢測你在這裏的環定位問題。總而言之,如果一個多邊形存在這個問題,那麼包絡角將是180°(這幾乎不是你想要的)。

我已經放棄了關於如何在上面的代碼中解決它的問題;在多邊形上調用ReorientObject()順時針變爲逆時針(反之亦然)。

最後,它看起來像你的行字符串完全包含在你的視口;我使用STContains()進行了測試。這就解釋了爲什麼你以前得到錯誤,當你認爲你的視口是一切但是視口!