Dividindo seu GeographyCollection em polígonos separados no Sql Server 2012 [Parte 2 de 2]

Na primeira parte desta coleção de protip , expliquei como dividir um GeographyCollectionem vários polígonos.

Tudo bem – mas por que você faria isso?

Alguns softwares espaciais não conseguem lidar GeographyCollections. Um bom exemplo disso é o RavenDb , que aproveita o projeto SpatialN para todos os cálculos espaciais.

Quando eu crio o índice espacial RavenDb e ele tenta fazer isso contra alguns dados de texto conhecido que é um GeographyCollection, este é o erro:

NtsGeometry does not support GeometryCollection but does support its subclasses.

Verificar o código-fonte SpatialN confirma que esta é a lógica definida.

Então o que nós podemos fazer?

Esta pode não ser a solução ideal , mas é uma boa solução.

Divida você GeographyCollectionem Polygons. Pegue o polígono com a grande área e use esse valor. Jogue fora todos os outros polígonos.

A ideia é muito simples e tem uma suposição massiva: a forma geralmente é uma forma principal com várias “ilhas” minúsculas fora dela. Então abandone as ilhas.

Não é à prova de idiotas, mas pode ser adequado para a maioria dos cenários.

Então, como podemos fazer isso? Vamos melhorar nosso código anterior.

SET NOCOUNT ON

-- Create the numbers table.
DECLARE
@counter INTEGER
DECLARE
@numberTable TABLE(Number INTEGER PRIMARY KEY)
SELECT
@counter = 1
WHILE
@counter <= 10000
BEGIN
INSERT INTO
@numberTable(number) VALUES (@counter)

SELECT
@counter = @counter + 1
END


-- Now extract the data.
-- NOTE: My shape boundaries are in a table called GeographyBoundaries.
SELECT TOP
1
a
.LocationId,
a
.OriginalBoundary.STGeometryN(b.number) AS Shape,
a
.OriginalBoundary.STGeometryN(b.number).STArea() AS Area,
a
.OriginalBoundary.STGeometryN(b.number).STArea() / a.OriginalBoundary.STArea() * 100.0 AS '% Area',
a
.OriginalBoundary.STGeometryN(b.number).ToString() AS WellKnownText
FROM
GeographyBoundaries a
INNER JOIN
@numberTable b ON b.number <= a.OriginalBoundary.STNumGeometries()
WHERE a
.LocationId = 5709978
ORDER BY a
.OriginalBoundary.STGeometryN(b.number).STArea() DESC

As principais coisas que adicionei aqui foram:

  • Ordenando por STArea() DESC(ordenar pelas áreas maiores, primeiro) – TOP 1– retorna apenas o primeiro resultado, nesta lista.
  • Mostre-me a porcentagem dessa área dividida em relação à forma total.

Então, agora, quando eu executar isso, aqui está o meu resultado:

resultado da amostra

  • Área: 602026064425,97
  • % Área: 99,8637901016668
  • WKT: POLYGON (((124.6706 ….

Agradável!

Outra ideia poderia ser juntar todos os Polygonsem um único MultiPolygontipo. Isso é claro, assumindo que todos os itens na GeographyCollectionestão Polygon's.

Para mim, estou feliz com o código acima, para os dados com os quais estou lidando .

HTH 🙂