2017-02-13 2 views
0

Ich habe eine SQL-Abfrage, wo ich zwei Geografievariablen deklariere, und dann versuche ich, den Mittelpunkt der Polygone zu finden, nachdem Werte zugewiesen wurden Variablen.Verwenden von EnvelopeCenter auf einer Geografievariable gibt nicht den richtigen Wert in SQL Server

Dies ist mein Code:

DECLARE @g1 GEOGRAPHY; 
DECLARE @g2 GEOGRAPHY; 

SET @g1 = geography::STGeomFromText('POLYGON((-90.06875038146973 35.512324341620996,-90.06767749786377 35.51504904492378,-90.06407260894775 35.51499664765537,-90.06381511688232 35.512219543493465,-90.06875038146973 35.512324341620996))',4326); 
SET @g2 = geography::STGeomFromText('POLYGON ((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))',4326); 

SELECT @g1 AS 'G1' , 
     @g2 AS 'G2'; 

SELECT 'G1' AS 'Polygon' , 
     @g1.EnvelopeCenter().Lat AS 'Lat' , 
     @g1.EnvelopeCenter().Long AS 'Long' 
UNION ALL 
SELECT 'G2' AS 'Polygon' , 
     @g2.EnvelopeCenter().Lat AS 'Lat' , 
     @g2.EnvelopeCenter().Long AS 'Long' 

nun für das zweite Polygon, es gibt das Zentrum lat/long-Wert korrekt als 47,6545001086162, -122,352999904254. Aber für die erste gibt es den Wert von 90, 0 zurück.

Warum bekomme ich nicht den richtigen Mittelpunkt für das erste Polygon? Wenn es aus irgendeinem Grund nicht möglich ist, gibt es einen anderen Weg, auf dem ich den Mittelpunkt für eine bestimmte WKT-Zeichenfolge finden kann?

Antwort

1

Jede geschlossene Linie auf der Oberfläche des Globus kann einen von zwei verschiedenen endlichen Räumen beschreiben. Um zu wissen, welcher Raum definiert wird, müssen Sie bestimmen, wo das "Innere" der Form ist.

In diesem Fall beschreibt G1 derzeit einen großen Teil des Globus minus eine kleine Menge von Raum um -90.066, 35.513.

Wenn Sie es wünschen, einen kleinen Teil der Welt zu beschreiben, dass umfasst -90,066, 35,513, dann müssen Sie die Reihenfolge der Punkte ändern, die Sie um die Form zu beschreiben verwenden:

DECLARE @g1 GEOGRAPHY; 
DECLARE @g2 GEOGRAPHY; 

SET @g1 = geography::STGeomFromText('POLYGON((
               -90.06875038146973 35.512324341620996, 
               -90.06381511688232 35.512219543493465, 
               -90.06407260894775 35.51499664765537, 
               -90.06767749786377 35.51504904492378, 
               -90.06875038146973 35.512324341620996 
              ))',4326); 
SET @g2 = geography::STGeomFromText('POLYGON ((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))',4326); 

SELECT @g1 AS 'G1' , 
     @g2 AS 'G2'; 

SELECT 'G1' AS 'Polygon' , 
     @g1.EnvelopeCenter().Lat AS 'Lat' , 
     @g1.EnvelopeCenter().Long AS 'Long' 
UNION ALL 
SELECT 'G2' AS 'Polygon' , 
     @g2.EnvelopeCenter().Lat AS 'Lat' , 
     @g2.EnvelopeCenter().Long AS 'Long' 

Ergebnis (2):

Polygon Lat     Long 
------- ---------------------- ---------------------- 
G1  35.5136474138606  -90.0660789036838 
G2  47.6545001086162  -122.352999904254 

Dies ist, weil es die Folge von Punkten ist die Beschreibung der Form, die verwendet wird, um die Innenseite gegen die Außenseite der Form zu bestimmen - es bezeichnet als die „linke Regel“.

+0

Das ist perfekt! 35.513, -90.066 ist, was ich erwartet habe zu sehen. Aber ich kontrolliere normalerweise nicht die Reihenfolge der eingegebenen Punkte, und einige meiner Polygone haben Löcher. Also gibt es eine Möglichkeit, den Raum einfach zu invertieren, wenn der Wert 90, 0 ist? Da das manuelle Ändern der Punktsequenz möglicherweise unordentlich wird, besonders wenn das Polygon Löcher hat. – Raj

+0

Wenn es nicht möglich ist, ist es in Ordnung. Ich habe festgestellt, dass es möglich ist, einen ähnlichen Wert mit der STCentroid() -Methode zu erhalten, die stattdessen den Schwerpunkt einer "Geometrie" -Variable zurückgibt (ich brauchte nur den ungefähren Wert). Und die Reihenfolge scheint in diesem Fall keine Rolle zu spielen. Aber ich habe mich nur gefragt, ob das möglich ist. Vielen Dank für die Lösung meines Problems! – Raj

+0

@Raj - du könntest vielleicht einen 'SANity Check' mit 'STArea' hinzufügen und wenn es ziemlich groß erscheint, könntest du' STDifference' zwischen der aktuellen Geografie und 'FullGlobe' verwenden? –

Verwandte Themen