Polygon
Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure
Un oggetto Polygon è una superficie bidimensionale archiviata come una sequenza di punti che definiscono un anello di delimitazione esterno e nessuno o più anelli interni.
Istanze Polygon
Un'istanza Polygon può essere formata da un anello che ha almeno tre punti distinti. Un'istanza Polygon può essere anche vuota.
L'anello esterno e ogni anello interno di un oggetto Polygon ne definiscono il limite. Lo spazio all'interno degli anelli definisce l'interno dell'oggetto Polygon.
La figura seguente mostra alcuni esempi di istanze Polygon .
Come indicato nell'illustrazione:
La figura 1 è un'istanza Polygon il cui limite è definito da un anello esterno e due anelli interni.
La figura 2 è un'istanza Polygon il cui limite è definito da un anello esterno e due anelli interni. L'area negli anelli interni è parte dell'esterno dell'istanza Polygon .
La figura 3 è un'istanza Polygon valida perché i suoi anelli interni si intersecano in un solo punto tangente.
Istanze accettate
Le istanze Polygon accettate sono istanze che possono essere archiviate in una variabile geometry o geography senza generare un'eccezione. Di seguito sono riportate le istanze Polygon accettate:
- Istanza Polygon vuota
- Istanza Polygon che ha un anello esterno accettabile (LineString) e zero o più anelli interni accettabili (LineStrings)
I criteri seguenti sono necessari affinché un anello (LineString) sia accettabile.
- L'istanza LineString deve essere accettata.
- L'istanza LineString deve avere almeno quattro punti.
- I punti iniziale e finale dell'istanza LineString devono corrispondere.
L'esempio seguente illustra le istanze Polygon accettate.
DECLARE @g1 geometry = 'POLYGON EMPTY';
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 1))';
DECLARE @g3 geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 3 3, 0 3, 0 0))';
DECLARE @g4 geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(3 0, 6 0, 6 3, 3 3, 3 0))';
DECLARE @g5 geometry = 'POLYGON((1 1, 1 1, 1 1, 1 1))';
Come illustrato in @g4
e @g5
è possibile che Polygon accettata non sia un'istanza Polygon valida. @g5
mostra anche che un'istanza Polygon, per essere accettata, deve contenere solo un anello con quattro punti qualsiasi.
Negli esempi seguenti viene generata una System.FormatException
perché le istanze Poligono non vengono accettate.
DECLARE @g1 geometry = 'POLYGON((1 1, 3 3, 1 1))';
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 5))';
@g1
non viene accettata perché l'istanza Linea spezzata per l'anello esterno non contiene un numero di punti sufficiente. @g2
non viene accettata perché il punto iniziale dell'istanza Linea spezzata dell'anello esterno non corrisponde al punto finale. Nell'esempio seguente è presente un anello esterno accettabile, ma l'anello interno non è accettabile. Viene inoltre generata un'eccezione System.FormatException
.
DECLARE @g geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 0 0))';
Istanze valide
Gli anelli interni di un Poligono possono toccare se stessi e toccarsi tra loro in singoli punti di tangenza, ma se gli anelli interni di un Poligono si incrociano, l'istanza non è valida.
Nell'esempio seguente vengono illustrate le istanze Polygon valide.
DECLARE @g1 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20))';
DECLARE @g2 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0))';
DECLARE @g3 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 0 10, -5 -10, -10 0))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid();
@g3
è valida perché i due anelli interni si toccano in un solo punto e non si incrociano. Nell'esempio seguente vengono illustrate istanze Polygon
non valide.
DECLARE @g1 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (20 0, 0 10, 0 -20, 20 0))';
DECLARE @g2 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (5 0, 1 5, 1 -5, 5 0))';
DECLARE @g3 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 0 10, 0 -10, -10 0))';
DECLARE @g4 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 1 5, 0 -10, -10 0))';
DECLARE @g5 geometry = 'POLYGON((10 0, 0 10, 0 -10, 10 0), (-20 -20, -20 20, 20 20, 20 -20, -20 -20) )';
DECLARE @g6 geometry = 'POLYGON((1 1, 1 1, 1 1, 1 1))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid(), @g6.STIsValid();
@g1
non è valida perché l'anello interno tocca l'anello esterno in due punti. @g2
non è valida perché il secondo anello interno si trova all'interno del primo anello interno. @g3
non è valida perché i due anelli interni si toccano in più punti consecutivi. @g4
non è valida perché gli interni dei due anelli interni si sovrappongono. @g5
non è valida perché l'anello esterno non è il primo anello. @g6
non è valida perché l'anello non presenta almeno tre punti distinti.
Orientamento dei dati spaziali
L'orientamento dell'anello di un poligono non è un fattore importante nel sistema planare. La specifica OGC Simple Features for SQL non impone un ordinamento degli anelli e SQL server non applica l’ordinamento degli anelli.
In un sistema ellissoidale, un poligono senza orientamento non ha significato o è ambiguo. Ad esempio, un anello intorno all'equatore descrive l'emisfero nord o sud? Se si utilizza il tipo di dati geography per archiviare l'istanza spaziale, è necessario specificare l'orientamento dell'anello e descrivere accuratamente la posizione dell'istanza.
L'interno del poligono in un sistema ellissoidale è definito dalla "regola della mano sinistra": se si immagina di camminare lungo l'anello di un poligono geografico, seguendo i punti nell'ordine in cui sono elencati, l'area a sinistra viene considerata come l'interno del poligono e l'area a destra come parte esterna del poligono.
Antiorario
DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 0 0, 20 0, 20 20, 0 20))', 4326);
SELECT @square;
Orario
DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 20 20, 20 0, 0 0, 0 20))', 4326);
SELECT @square;
Quando in SQL Server il livello di compatibilità è uguale o minore di 100, al tipo di dati geography si applicano le restrizioni seguenti:
Ogni istanza geography deve adattarsi all'interno di un singolo emisfero. Non è possibile archiviare oggetti spaziali con dimensioni maggiori di un emisfero.
Qualsiasi istanza geography di una rappresentazione Well-Known Text (WKT) o Well-Known Binary (WKB) OCG che produca un oggetto più grande di un emisfero genera ArgumentException.
I metodi del tipo di dati geografici che richiedono l'input di due istanze geografiche, ad esempio STIntersection(), STUnion(), STDifference() e STSymDifference(), restituiranno Null se i risultati dei metodi non si adattano all’interno di un singolo emisfero. Anche STBuffer() restituirà Null se l'output supera un singolo emisfero.
L'orientamento può essere invertito sfruttando il metodo esteso ReorientObject.
Esempi
Esempio A.
L'esempio seguente crea un'istanza semplice di geometry
Polygon
con un foro e SRID 10.
DECLARE @g geometry;
SET @g = geometry::STPolyFromText(
'POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))',
10);
Esempio B.
Un'istanza non valida può essere inserita e convertita in un'istanza geometry
valida. Nell'esempio seguente di un Polygon
, gli anelli interni ed esterni si sovrappongono e l'istanza non è valida.
DECLARE @g geometry;
SET @g = geometry::Parse(
'POLYGON((1 0, 0 1, 1 2, 2 1, 1 0), (2 0, 1 1, 2 2, 3 1, 2 0))'
);
Esempio C.
Nell'esempio seguente, l'istanza non valida è resa valida con MakeValid()
.
SET @g = @g.MakeValid();
SELECT @g.ToString();
L'istanza geometry
restituita dall'esempio precedente è un MultiPolygon
.
MULTIPOLYGON (((2 0, 3 1, 2 2, 1.5 1.5, 2 1, 1.5 0.5, 2 0)),
((1 0, 1.5 0.5, 1 1, 1.5 1.5, 1 2, 0 1, 1 0)))
Esempio D.
Questo è un altro esempio di conversione di un'istanza non valida in un'istanza geometry valida. Nell'esempio seguente l'istanza Polygon
è stata creata utilizzando tre punti esattamente uguali:
DECLARE @g geometry
SET @g = geometry::Parse('POLYGON((1 3, 1 3, 1 3, 1 3))');
SET @g = @g.MakeValid();
SELECT @g.ToString()
L'istanza geometry restituita sopra è Point(1 3)
. Se l'istanza Polygon
indicata è POLYGON((1 3, 1 5, 1 3, 1 3))
, MakeValid()
restituirà LINESTRING(1 3, 1 5)
.
Vedi anche
STArea (tipo di dati geometry)
STExteriorRing (tipo di dati geometry)
STNumInteriorRing (tipo di dati geometry)
STInteriorRingN (tipo di dati geometry)
STCentroid (tipo di dati geometry)
STPointOnSurface (tipo di dati geometry)
MultiPolygon
Dati spaziali (SQL Server)
STIsValid (tipo di dati geography)
STIsValid (tipo di dati geometry)