Esta es una pregunta de geometría de SQL Server aparentemente simple que pensé que tendría una solución lista para usar, pero no tengo suerte para encontrarla.
Mi intención es seleccionar todos los registros dentro de una tabla que tengan polígonos anidados (contenidos) dentro de un polígono más grande de otra tabla. Esperaba funciones STWithin
y STContains
como las soluciones que necesitaba, pero desafortunadamente, ambas identifican solo los polígonos internos dentro de los anidados en el polígono más grande, no aquellos polígonos anidados que están tocando el límite del polígono más grande. Ver imagen por ejemplo.
Una opción alternativa que funcionó para mis necesidades fue STIntersection
. Sin embargo, el problema con esta función es que solo devuelve la columna de geometría. Me gustaría obtener el ID de registro en su lugar. ¿Alguien tiene una sugerencia sobre cómo se puede hacer esto?
STWithin
:
select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STWithin(b.shape) = 1
where b.mktname = 'Loop'
STContains
:
select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on b.shape.STContains(a.shape) = 1
where b.mktname = 'Loop'
STIntersection
:
select a.shape.STIntersection(b.shape)
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'
Editar:
Una sugerencia fue omitir STIntersection
y usar únicamente de la STIntersects
siguiente manera:
STIntersects
:
select a.bg10
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'
El problema con este enfoque es que STIntersects
parece seleccionar todos los polígonos dentro o fuera y tocar el polígono más grande, no solo los estrictamente dentro. Ver imagen por ejemplo.
fuente
STContains
oSTWithin
. Realmente no es un buen truco, pero obtendrá los resultados que desea. La otra opción sería hacer las intersecciones STI con una comparación del área de intersección y el área de polígonos.Respuestas:
En teoría, las consultas que ha realizado deberían devolver los polígonos que dijo que no se han devuelto. Eso me hace sospechar que puede estar encontrando problemas de error de punto flotante que SQL Server tiene con los tipos de datos espaciales. De ahí mi comentario sobre amortiguar el polígono delimitador con una cantidad mínima.
Entonces, algo como lo siguiente debería obtener los resultados que desea.
Aquí hay un ejemplo rápido del comportamiento esperado de algunos de los métodos espaciales.
Resultados
fuente
La consulta de intersección debería tener este aspecto (suponiendo que desea que todos los registros vuelvan de 'a'):
Si desea solo las áreas de a que se cruzan b (es decir, recortar aa b), entonces agregue la intersección STI
Pero esto no te da los polígonos que están dentro de b todavía ...
Este tipo de polígono en polígono es muy irritante con los límites y su coincidencia: para estar 'Dentro', los límites de a no pueden coincidir con los límites de b, lo mismo ocurre con 'Contiene'.
Según estas definiciones, ¿cuántos de sus polígonos en a están realmente dentro de b ...?
Entonces, ¿desea almacenar en búfer b antes de seleccionar polígonos en a que están dentro? ¿O hacer un buffer negativo en un?
No estoy seguro de cuál es la respuesta exacta aquí ...
fuente