2016-07-05 3 views
0

Ich habe einen Fall, wo ich Kartenobjekte im Viewport von Benutzern laden möchte. DieseDbGeography - Wählen Sie Polygone/Linienfolgen innerhalb des Polygons

ist, wie ich Benutzer Ansichtsfenster Rechteck erstellen:

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

Dann möchte ich alle Objekte auszuwählen (Punkte, Polylinien, Polygone, innerhalb dieses Rechtecks):

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

Alles bis hier funktioniert gut. Das Problem tritt auf, wenn PolyLine/Polygon nicht vollständig im Ansichtsfensterpolygon enthalten ist. In diesem Fall wird es ignoriert und ich bekomme "keine Objekte" anstelle von Objekten, wo einige Punkte/Kanten außerhalb des Ansichtsfensters liegen.

Gibt es eine Alternative zu "Intersects"? Ich möchte Objekte auswählen, die im Ansichtsfenster-Rechteck enthalten sind, unabhängig davon, ob sie sich überhaupt in der Ansicht befinden oder ob nur ein kleiner Teil von ihnen innerhalb des Rechtecks ​​des Ansichtsfensters liegt.

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

Objekt, das nur teilweise innerhalb viewport_rectangle befindet und sollte werden als Ergebnis zurückgegeben:

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)

Ein Teil von LINQ generierte Abfrage:

SELECT [Filter1]. [ObjektId] AS [ObjektId], [Filter1]. [StandortGeographic] AS [StandortGeographic], FROM (SELECT [Ausdehnung1]. [ObjektId] AS [ObjektId], [Ausdehnung1]. [LocationGeographic ] AS [LocationGeographic] FROM [DBO]. [MapObjects] AS [Extent1] WHERE (([Filter1]. [LocationGeographic] .STIntersects (@ p__linq__0)) <> Gusstück (1 als Bit)) ) AS [ Project1]

Editiert: die richtige Reihenfolge von viewport_rectangle sollte sein:

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

Intersects sollten es tun (angenommen, dass es 'STIntersects()' auf der DB-Seite implementiert). Können Sie Daten bereitstellen, die das von Ihnen vorgeschlagene Verhalten aufweisen? Eine Spur von dem, was an die DB weitergegeben wird, wäre ebenfalls hilfreich. –

+0

Nur zur Basisfrage hinzugefügt. Hoffe es hilft dir, den Grund des Verhaltens zu bestimmen. – Tadej

Antwort

1

Sie haben anscheinend ein Problem mit der Ringausrichtung bei Ihrem Polygon. Die Reihenfolge, in der Sie Ihre Punkte angeben, ist wichtig. Das Polygon, wie Sie es definiert haben, ist der gesamte Globus minus ein sehr kleines Quadrat (vermutlich Ihr gewünschtes Ansichtsfenster). Wie habe ich das festgestellt?

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 

Am besten Sie lesen Sie auf die EnvelopeAngle() Methode selbst. Aber ich sage das - ich benutze es als eine schnelle Heuristik, um das Problem der Ringorientierung zu erkennen, das Sie hier haben. Wenn ein Polygon dieses Problem hat, ist der Umschlagwinkel immer 180 (was fast nie beabsichtigt ist).

Ich habe auch die Pointe, wie man es in dem Code oben beheben kann verraten; Aufruf ReorientObject() auf dem Polygon ändert sich im Uhrzeigersinn gegen den Uhrzeigersinn (und umgekehrt).

Endlich sieht es so aus, als ob Ihre Zeile vollständig in Ihrem Ansichtsfenster enthalten wäre. Ich habe mit STContains() getestet. Was erklärt, warum Sie vorher falsch waren, als das, was Sie dachten, war Ihr Viewport war alles aber das Viewport!

Verwandte Themen