Este es un mapa de contorno para el que están disponibles todos los polígonos de los niveles.
Preguntemos ¿Cómo alisar los polígonos manteniendo todos los vértices en su ubicación exacta?
De hecho, el contorno se realiza sobre una cuadrícula, por lo que se puede sugerir que se suavicen los datos de la cuadrícula y, por lo tanto, el contorno resultante será más suave. Tenga en cuenta que esto no funciona como mi deseo, ya que la función de suavizado como el filtro gaussiano eliminará pequeños paquetes de datos y cambiará el rango de la tercera variable, por ejemplo, la altura, que no están permitidos en mi aplicación.
En realidad estoy buscando un trozo de código (preferiblemente en Python ) que puede hacer el suavizado de polígonos 2D (de cualquier tipo: convexo, cóncavo, auto-intersección, etc) razonablemente indoloro (olvídate de las páginas de códigos) y preciso.
Para su información, hay una función en ArcGIS que lo hace perfectamente, pero usar aplicaciones comerciales de terceros no es mi opción para esta cuestión.
1)
Scipy.interpolate:
Como ves, las splines resultantes (en rojo) no son satisfactorias.
2)
Aquí está el resultado usando el código dado en aquí . No está funcionando bien.
3)
Para mí la mejor solución debería ser algo como la siguiente figura en la que un cuadrado se está suavizando gradualmente cambiando sólo un valor. Espero un concepto similar para suavizar cualquier forma de polígonos.
Satisfacer la condición de que la spline pase por los puntos:
4)
Aquí está mi implementación de la "idea de Whuber" línea por línea en Python en sus datos. Posiblemente hay algunos errores ya que los resultados no son buenos.
K=2 es un desastre y lo mismo para k>=4.
5)
He eliminado un punto en el lugar problemático y la spline resultante es ahora idéntica a la de whuber. Pero sigue siendo una pregunta que por qué el método no funciona para todos los casos?
6)
Un buen alisado para los datos de Whuber puede ser el siguiente (dibujado con un software de gráficos vectoriales) en el que se ha añadido suavemente un punto extra (comparar con la actualización
4):
7)
Vea el resultado de la versión Python del código de Whuber para algunas formas icónicas:
Nota que el método parece no funcionar para las polilíneas. Para la polilínea de la esquina (contorno) el verde es lo que quiero pero obtuve el rojo. Esto debe ser resuelto ya que los mapas de contorno son siempre polilíneas aunque las polilíneas cerradas pueden ser tratadas como polígonos como en mis ejemplos. Tampoco es que el problema surgido en la actualización 4 no se haya solucionado todavía.
8) [mi última]
Aquí está la solución final (¡no es perfecta!):
Recuerda que tendrás que hacer algo en la zona señalada por las estrellas. Quizá haya un error en mi código o el método propuesto necesite un mayor desarrollo para considerar todas las situaciones y proporcionar los resultados deseados.
0 votos
¿Cómo se generan los contornos "poligonales"? ¿No serían siempre líneas, ya que un contorno que cruza el borde de un MDE nunca se cerraría sobre sí mismo?
0 votos
He utilizado la función v.generalize en GRASS para hacer el suavizado de las líneas de contorno con resultados decentes, aunque puede tomar un tiempo para los mapas con contornos muy densos.
0 votos
@pistachionut Puedes considerar que los niveles de contorno son polilíneas. Estoy buscando código puro en la primera etapa. Si no está disponible, entonces paquete ligero para Python.
0 votos
Tal vez, mirar a scipy.org/Cookbook/Interpolation porque parece que quieres spline
0 votos
@PolyGeo Gracias por el enlace. He puesto algunos resultados en la pregunta, actualización 1. ¡No son para nada satisfactorios!
0 votos
Esta respuesta puede ayudar: stackoverflow.com/questions/246525/
0 votos
Me parece que algunos de los artefactos son causados por la repetición de puntos, causando una esquina en la curva. ¿Tal vez alimentar la función con la definición del polígono sin eliminar el punto de inicio / final duplicado? (O en realidad, podría ser lo contrario, que Scipy.interpolate no considera la curva un bucle)
0 votos
@relet Creo que tu segunda suposición es correcta. Siempre hay una esquina. ¡Además, las splines dibujadas no están lo suficientemente cerca de los polígonos!
0 votos
@Pablo ya he probado tu enlace dado con muchas mejoras. Sin embargo siempre hay una esquina molesta en la spline resultante. En efecto, la spline parte de un punto y termina en él. He añadido mis resultados en la actualización 2.
0 votos
Actualización 1: ¿por qué los resultados son "insatisfactorios"? ¿Se debe quizás a que no está utilizando una spline circular (periódica)? Un sencillo truco te ayudará: amplía cíclicamente la lista de vértices en ambos extremos. Añade tantos vértices como el orden de la spline (por ejemplo, para una spline cúbica añade tres vértices en cada extremo). Calcula el spline y restríngelo a la lista original de vértices. Ahora no habrá efectos en los extremos.
0 votos
@whuber Para mí no son satisfactorios 1) siempre hay un efecto de esquina 2) hay grandes distancias entre la curva y los segmentos 3) no mantienen la forma general preservada.
0 votos
(1) Cualquier "efecto de esquina" se debe a que está duplicando un vértice (para que sirva de inicio y final del límite del polígono). Elimine el vértice duplicado. (2) Controla las distancias utilizando diferentes tipos de splines. Por ejemplo, tome una combinación lineal de un spline y el polígono original. (3) Por definición, suavizar un polígono cambiará su forma. No se puede esperar que se conserve.
0 votos
@whuber Para el caso mostrado en la actualización 4 no hay ningún punto duplicado, ¡todavía hay problema de auto-intersección!
0 votos
Eso es casi seguro que es un error en su código. Esa cúspide no es posible utilizando una spline cúbica.
0 votos
@whuber Añadir
xy = rbind(xy,c(1.8,-0.8))
verás lo que quiero decir. La misma cúspide en el resultado de R.1 votos
@Pablo La curva Bezier de tu enlace funciona bien para polilíneas. La de Whuber funciona casi bien para polígonos. Así que juntas podrían resolver la duda. Muchas gracias por compartir tus conocimientos de forma gratuita.
0 votos
Pues sí: si fuerzas una cúspide mediante un muestreo denso cerca de un vértice, ¡obtendrás una cúspide! Se podría pensar que es una característica deseable del método de suavizado. Para que los alisadores funcionen bien, hay que dejar espacios suficientemente grandes entre los vértices o relajar el requisito de que el alisador pase por los vértices.
0 votos
Re Edición 7: Para splinear polilíneas, simplemente omita la envoltura preliminar de los vértices (ponga
k=0
en mi solución: Lo he editado para que ese caso funcione correctamente). Re las curvas Bezier: no logran lo que quieres, porque no pasan por los vértices.0 votos
@whuber Sí, tienes razón. Las curvas Bezier no pasan por los puntos dados. Actualicé mi código según tu recomendación y obtuve los resultados mostrados en la actualización 8.
0 votos
Interpolación con curvas de Bézier. Un método muy sencillo para suavizar polígonos: antigrain.com/research/bezier_interpolation
0 votos
Pregunta similar y buena solución: stackoverflow.com/a/31466013/2829863
0 votos
TopoJSON puede ser una opción. Se trata de un modelo de datos topológicos, como su nombre indica, y los métodos de simplificación están disponibles a través de la API. Consulte esta entrada del blog para obtener más información. - perrygeo.com/tag/topojson.html .