Condividi tramite


Polygon

Un Polygon è una superficie bidimensionale archiviata come una sequenza di punti che definiscono un anello di delimitazione esterno e zero 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 Polygon ne definiscono il limite. Lo spazio all'interno degli anelli definisce l'interno del Polygon.

Nell'illustrazione seguente vengono riportati esempi di istanze Polygon.

Esempi di istanze di geometria Polygon

Come indicato nell'illustrazione:

  1. La figura 1 è un'istanza Polygon il cui limite è definito da un anello esterno.

  2. 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.

  3. 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 vengono elencate istanze Polygon accettate per il tipo geometry:

  • Istanza Polygon vuota

  • Istanza Polygon che ha un anello esterno accettabile e zero o più anelli interni accettabili

I criteri seguenti sono necessari affinché un anello sia accettabile.

  • L'istanza LineString deve essere accettata.

  • L'istanza LineString deve avere almeno quattro punti che includano tre punti distinti.

  • Il punto iniziale e quello finale dell'istanza LineString devono avere gli stessi valori X e Y.

    Nota

    I valori Z e M vengono ignorati.

Un'istanza Polygon di un tipo geography viene accettata solo se l'istanza è valida. Per ulteriori informazioni sulle istanze Polygon valide per il tipo geography, vedere BkmkValidGeographyPolygons.

Nell'esempio seguente vengono illustrate 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))';

Come illustrato in @g4, è possibile che un'istanza Polygon accettata non sia un'istanza Polygon valida. Negli esempi seguenti viene generata un'eccezione System.FormatException in quanto le istanze Polygon non sono 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 è accettato in quanto l'istanza LineString per l'anello esterno non contiene abbastanza punti. @g2 non è accettato perché il punto iniziale dell'anello esterno dell'istanza LineString non corrisponde al punto finale. Nell'esempio seguente, l'anello esterno è accettabile ma non quello interno. Anche questo genera 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 Polygon possono toccare se stessi e toccarsi tra di loro in singoli punti tangenti, ma se gli anelli interni di un Polygon 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 è valido perché i due anelli interni si toccano in un solo punto e non si incrociano tra di loro. Nell'esempio seguente vengono illustrate le istanze Polygon che non sono 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))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid();

@g1 non è valido perché l'anello interno tocca l'anello esterno in due posti. @g2 non è valido perché il secondo anello interno è all'interno del primo anello interno. @g3 non è valido perché i due anelli interni toccano più punti consecutivi. @g4 non è valido perché le parti interne dei due anelli interni si sovrappongono.

Tipo di dati geometry

Affinché un'istanza Polygon di tipo geometry sia valida, deve soddisfare i criteri seguenti:

  1. Il primo anello è l'anello esterno.

  2. Tutti gli anelli interni si trovano all'interno dell'anello esterno.

  3. Nessun anello interno si trova all'interno di un altro anello interno.

  4. Nessun anello incrocia se stesso o un altro anello.

  5. Nessuno dei due anelli può condividere lo stesso bordo.

  6. L'interno di un anello interno non può sovrapporsi all'interno di un altro anello interno.

  7. Tutti gli anelli possono toccare solo se stessi o un altro anello in un numero finito di punti tangenti o in nessuno.

  8. La parte interna dell'istanza Polygon è connessa. Deve esistere almeno un percorso tra due punti interni dell'istanza che si trova completamente all'interno dell'istanza.

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 è valido perché i due anelli interni si toccano in un solo punto e non si incrociano tra di loro. Nell'esempio seguente vengono illustrate le istanze Polygon che non sono 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) )';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid();

@g1 non è valido perché l'anello interno tocca l'anello esterno in due posti. @g2 non è valido perché il secondo anello interno è all'interno del primo anello interno. @g3 non è valido perché i due anelli interni toccano più punti consecutivi. @g4 non è valido perché le parti interne dei due anelli interni si sovrappongono. @g5 non è valido perché il primo anello è interno e il secondo anello è esterno.

Tipo di dati geography

Affinché un'istanza Polygon di tipo geography sia valida, deve soddisfare i criteri seguenti:

  1. L'istanza deve soddisfare tutte le regole necessarie affinché sia un'istanza Polygon accettata di tipo geometry.

  2. La parte interno dell'istanza è connessa tramite una regola del lato sinistro.

  3. L'istanza può essere appropriata a un emisfero.

  4. Nessun anello incrocia se stesso o qualsiasi altro anello.

  5. Tutti gli anelli possono toccare solo se stessi o qualsiasi altro anello in un numero finito di punti tangenti o in nessuno.

Nell'esempio seguente viene generata un'eccezione Microsoft.SqlServer.Types.GLArgumentException perché l'istanza Polygon supera un emisfero.

DECLARE @g geography = 'POLYGON((-122.358 47.653, 122.348 47.649, 122.348 47.658, 122.358 47.658, -122.358 47.653))';

Nell'esempio riportato di seguito viene mostrata un'istanza Polygon valida per il tipo geography.

DECLARE @g geography = 'POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))';

Esempi

Nell'esempio seguente viene creata un'istanza geometryPolygon semplice 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);

Un'stanzache non è valida può essere immessa 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))');

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