Polígono

Un Polygon es una superficie bidimensional almacenada como una secuencia de puntos que definen un anillo delimitador exterior y cero o más anillos interiores.

Instancias de Polygon

Una instancia de Polygon se puede formar a partir de un anillo que tenga al menos tres puntos distintos. Una instancia de Polygon también puede estar vacía.

Los límites de una instancia de Polygon los define su anillo exterior junto con los anillos interiores que tenga. El espacio encerrado dentro de los anillos define el interior de la instancia de Polygon.

La ilustración siguiente muestra ejemplos de instancias de Polygon.

Ejemplos de instancias Polygon de geometry

Como se muestra en la ilustración:

  1. La ilustración 1 es una instancia de Polygon cuyo límite está definido mediante un anillo exterior.

  2. La ilustración 2 es una instancia de Polygon cuyo límite está definido mediante un anillo exterior y dos anillos interiores. El área situada dentro de los anillos interiores forma parte del exterior de la instancia de Polygon.

  3. La ilustración 3 es una instancia de Polygon válida porque la intersección de sus anillos interiores se realiza en un solo punto tangente.

Instancias aceptadas

Las instancias Polygon aceptadas son instancias que pueden estar almacenadas en una variable geometry o geography sin producir una excepción. Las siguientes son instancias de Polygon aceptadas para el tipo de geometry:

  • Una instancia de Polygon vacía

  • Una instancia de Polygon que tiene un anillo exterior aceptable y cero o más anillos interiores aceptables

Los siguientes criterios se necesitan para que un anillo sea aceptable.

  • El tipo de instancia de LineString debe aceptarse.

  • La instancia de LineString debe tener al menos cuatro puntos que incluyan tres puntos distintos.

  • Los puntos final e inicial de la instancia de LineString deben tener los mismos valores X e Y.

    Nota

    Los valores Z y M se omiten.

Una instancia de Polygon de tipo geography solo se acepta si la instancia es válida. Para obtener más información sobre las instancias de Polygon válidas para el tipo geography, vea BkmkValidGeographyPolygons.

El ejemplo siguiente muestra las instancias de Polygon aceptadas.

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

Como @g4 muestra que una instancia de Polygon aceptada puede no ser una instancia de Polygon válida. Los siguientes ejemplos generan una System.FormatException porque no se aceptan las instancias de Polygon.

DECLARE @g1 geometry = 'POLYGON((1 1, 3 3, 1 1))';
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 5))';

@g1 no se acepta porque la instancia de LineString para el anillo exterior no contiene suficientes puntos. @g2 no se acepta porque el punto inicial de la instancia de LineString del anillo exterior no es el mismo que el final. El siguiente ejemplo tiene un anillo exterior aceptable, pero el anillo interior no lo es. Esto también genera una System.FormatException.

DECLARE @g geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 0 0))';

Instancias válidas

Los anillos interiores de una instancia de Polygon pueden tocarse a sí mismos y unos con otros en puntos tangentes únicos, pero si dichos anillos se cruzan, la instancia de Polygon no es válida.

El ejemplo siguiente muestra las instancias de Polygon válidas.

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 es válida porque los dos anillos interiores se tocan en un punto único y no se cruzan entre sí. El siguiente ejemplo muestra instancias de Polygon que no son válidas.

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 no es válida porque el anillo interior toca el anillo exterior en dos lugares. @g2 no es válida porque el segundo anillo interno está dentro del primer anillo interno. @g3 no es válida porque los dos anillos internos se tocan en varios puntos consecutivos. @g4 no es válida porque el interior de los dos anillos internos se superponen.

Tipo de datos Geometry

Para que una instancia de Polygon de un tipo geometry sea válida, tiene que cumplir los siguientes criterios:

  1. El primer anillo es el exterior.

  2. Todos los anillos interiores se quedan dentro del anillo exterior.

  3. Ningún anillo interior se queda dentro de otro anillo interior.

  4. Ningún anillo se cruza a sí mismo o a otro anillo.

  5. Ninguno de los dos anillos puede compartir el mismo perímetro.

  6. El interior de un anillo interior no puede superponerse con el interior de otro anillo interior.

  7. Todos los anillos solo pueden tocarse entre ellos o a otro anillo en cero o un número finito de puntos tangentes.

  8. El interior de la instancia de Polygon está conectado. Debe existir al menos una ruta entre dos puntos interiores cualesquiera de la instancia que estén completamente dentro de la instancia.

El ejemplo siguiente muestra las instancias de Polygon válidas.

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 es válida porque los dos anillos interiores se tocan en un punto único y no se cruzan entre sí. El siguiente ejemplo muestra instancias de Polygon que no son válidas.

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 no es válida porque el anillo interior toca el anillo exterior en dos lugares. @g2 no es válida porque el segundo anillo interno está dentro del primer anillo interno. @g3 no es válida porque los dos anillos internos se tocan en varios puntos consecutivos. @g4 no es válida porque el interior de los dos anillos internos se superponen. @g5 no es válida porque el primer anillo es interior y el segundo es exterior.

Tipo de datos Geography

Para que una instancia de Polygon de un tipo geography sea válida, tiene que cumplir los siguientes criterios:

  1. La instancia debe cumplir todas las reglas requeridas para ser una instancia de Polygon aceptada de tipo geometry.

  2. El interior de la instancia se conecta utilizando una regla de mano izquierda.

  3. La instancia puede caber en un hemisferio.

  4. Ningún anillo se cruza a sí mismo o a otro anillo.

  5. Todos los anillos solo pueden tocarse entre ellos o a otro anillo en cero o un número finito de puntos tangentes.

El siguiente ejemplo genera una Microsoft.SqlServer.Types.GLArgumentException porque la instancia de Polygon supera un hemisferio.

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

El siguiente ejemplo muestra una instancia de Polygon válida para el 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))';

Ejemplos

El ejemplo siguiente crea una instancia sencilla de geometryPolygon con un hueco y un SRID de 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);

Es posible especificar una instancia no válida y convertirla en una instancia de geometry válida. En el ejemplo siguiente de Polygon, se superponen los anillos interiores y el exterior, y la instancia no es válida.

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

En el ejemplo siguiente, la instancia no válida se hace válida con MakeValid().

SET @g = @g.MakeValid();
SELECT @g.ToString();

La instancia de geometry devuelta por el ejemplo anterior es de tipo 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)))