Necesito encontrar un centroide (o punto de etiqueta) para polígonos de forma irregular en Google Maps. Estoy mostrando InfoWindows para parcelas y necesito un lugar para anclar la InfoWindow que se garantiza que estará en la superficie. Ver imágenes a continuación.
En realidad, no necesito nada específico de Google Maps, solo busco una idea de cómo encontrar automáticamente este punto.
Mi primera idea fue encontrar el centroide "falso" tomando el lat y el lngs promedio y colocando los puntos aleatoriamente desde allí hasta encontrar uno que interseque el polígono. Ya tengo el código de punto en el polígono. Esto me parece terriblemente "hacky".
Debo señalar que no tengo acceso a ninguno de los códigos del lado del servidor que generan la geometría, por lo que no puedo hacer nada como ST_PointOnSurface (the_geom).
Es posible que desee ver esto: http://github.com/tparkin/Google-Maps-Point-in-Polygon
Parece utilizar un algoritmo de Casting de rayos que debe coincidir con el caso que presentó.
Hay una publicación de blog al respecto aquí. http://appdelegateinc.com/blog/2010/05/16/point-in-polygon-checking/
fuente
Un algoritmo ESRI (más antiguo) calcula el centro de masa y, después de probarlo para su inclusión en el polígono, lo mueve horizontalmente si es necesario hasta que se encuentre dentro del polígono. (Esto podría hacerse de muchas maneras dependiendo de qué operaciones fundamentales estén disponibles dentro de su entorno de programación). Esto tiende a producir puntos de etiqueta bastante cerca del centro visual del polígono: pruébelo en la ilustración.
fuente
Resolví mi problema extendiendo el popular código epoly de http://econym.org.uk/gmap . Básicamente lo que terminé haciendo fue:
Código de epoly extendido a continuación:
Todavía un poco hacky pero parece funcionar.
fuente
Otro algoritmo 'sucio' para hacer eso:
Toma el cuadro delimitador de la geometría
(Xmax, Ymax, Xmin, Ymin)
Haga un bucle hasta que se encuentre un punto aleatorio
( Xmin+rand*(Xmax-Xmin), Ymin+rand*(Ymax-Ymin) )
dentro de la geometría (usando Google-Maps-Point-in-Polygon )fuente
A la luz de su reciente aclaración de que preferiría una ubicación estrictamente interior, podría seleccionar cualquier punto en la Transformación del Eje Medial que no esté también en el límite del polígono. (Si no tiene código para un MAT, puede aproximarlo almacenando negativamente el polígono. Una búsqueda binaria o secante producirá rápidamente un pequeño polígono interior que se aproxima a parte de MAT; use cualquier punto en su límite).
fuente
¿Por qué no usar el centroide solo para la posición vertical (latitud)? Luego, puede colocar la etiqueta horizontalmente seleccionando la longitud promedio en esa latitud . (Para esto, deberías encontrar el valor de longitud para un borde de polígono en una latitud específica, lo que no debería darte ningún problema).
Además, tenga cuidado con las formas en U y las más complejas. :) Posiblemente para aquellos, elija el promedio del par de longitudes más a la derecha (cada par correspondería a una porción del polígono), ya que la ventana de información está orientada de esa manera?
Esto también le da un poco más de control sobre el posicionamiento; por ejemplo, podría ser bueno colocar la ventana de información en 66 o 75% verticalmente, para dejar más polígono visible. (¡O puede que no! Pero tienes la perilla para ajustar).
fuente
¿Qué tal si usas el punto en el que el usuario hizo clic para seleccionarlo, si es seleccionado por el usuario que lo es?
fuente
Estoy tratando de resolver esto también. He impuesto una condición a mis polígonos de que no pueden tener líneas de cruce que entren en lo que describiré.
Entonces, mi enfoque usa triangulación. Tome un vértice aleatorio (posiblemente tomar un vértice en el extremo N, E, W o S puede simplificar las cosas).
Desde este vértice, dibuje líneas al vértice a un vértice de distancia, es decir, si su vértice es el vértice 3, mire el vértice 3 + 2.
Construya una línea desde su vértice original hasta este vértice. Si la línea construida:
Entonces has construido un triángulo que está dentro del polígono. Si el vértice exitoso fue n + 2, entonces su triángulo es {n, n + 1, n + 2}, al que nos referiremos como {v, v1, v2}. De lo contrario, intente con el siguiente vértice y continúe hasta que se hayan probado todos los vértices.
Cuando encuentre un triángulo, encuentre el centro de ese punto tomando una línea desde el vértice v hasta el punto medio de v1 y v2. Se garantiza que el punto medio de esa línea estará dentro del triángulo y dentro del polígono.
Todavía no he codificado esto, pero puedo ver, al pensarlo, que un polígono con líneas cruzadas de hecho causará algunas condiciones exóticas donde esto no funciona. Si ese es el tipo de polígonos que tiene, necesitaría probar cada segmento de línea en el polígono y asegurarse de que no se haya cruzado. Omita los segmentos de línea que se cruzan, y creo que funcionará.
fuente
https://github.com/mapbox/polylabel puede ser útil (javascript y C ++). Implicación de C # aquí: https://gist.github.com/dfaivre/acfef42cdbf411555956e9eba65dd30d .
Pregunta SO original aquí: /programming//a/38522611/79113
fuente