linestring - PHP/Mongo geoJSON Loop no es válido
mongodb import geojson (2)
Estoy pasando algunas coordenadas a Mongo para hacer una búsqueda geográfica. Funciona bien si las coordenadas no se intersecan (por ejemplo, una figura ocho). Pero cuando dos líneas se intersecan da el loop is not valid
. ¿Hay alguna manera de encontrar la intersección y dividir todos estos bucles?
Tenga en cuenta que podría haber muchos.
EDITAR: he añadido la consulta de muestra y error. Tenga en cuenta que entiendo por qué está sucediendo, me pregunto si hay alguna forma conocida de dividir esos bucles en polígonos separados (algún algoritmo o dentro de Mongo).
Consulta:
db.items.find({
"address.location": {
"$geoWithin": {
"$geometry": {
"type": "Polygon",
"coordinates": [[
[-97.209091, 49.905691],
[-97.206345, 49.918072],
[-97.178879, 49.919399],
[-97.165146, 49.907903],
[-97.164459, 49.892865],
[-97.180939, 49.889326],
[-97.197418, 49.895077],
[-97.200165, 49.902596],
[-97.203598, 49.919399],
[-97.216644, 49.928682],
[-97.244797, 49.927356],
[-97.255096, 49.913209],
[-97.209091, 49.905691]
]]
}
}
}
});
Error:
Error: error: {
"waitedMS" : NumberLong(0),
"ok" : 0,
"errmsg" : "Loop is not valid: [
[ -97.209091, 49.905691 ]
[ -97.206345, 49.918072 ],
[ -97.17887899999999, 49.919399 ],
[ -97.16514599999999, 49.907903 ],
[ -97.16445899999999, 49.892865 ],
[ -97.180939, 49.889326 ],
[ -97.197418, 49.895077 ],
[ -97.200165, 49.902596 ],
[ -97.203598, 49.919399 ],
[ -97.216644, 49.928682 ],
[ -97.24479700000001, 49.927356 ],
[ -97.25509599999999, 49.913209 ],
[ -97.209091, 49.905691 ]
]
Edges 1 and 7 cross.
Edge locations in degrees: [-97.2063450, 49.9180720]-[-97.1788790, 49.9193990]
and [-97.2001650, 49.9025960]-[-97.2035980, 49.9193990]
",
"code" : 2
}
ACTUALIZAR
He añadido una imagen de un enfoque de fuerza bruta.
- Básicamente está haciendo una mirada al frente en intersecciones.
- Si encuentra uno, intercambia los puntos para que permanezca dentro de un bucle.
- Agregaría el corte como un "punto de inicio" en alguna cola.
- Cuando una mirada hacia adelante da la vuelta y encuentra su propio punto de partida, tenemos un bucle.
- Luego continúe con la cola del "punto de inicio" hasta que esté vacía.
- El nuevo conjunto de polígonos debe contener todos los bucles separados (en teoría).
Sin embargo, hay algunos problemas con esto, puede ser bastante caro pasar por todos estos bucles. Digamos que un máximo de 50 puntos sería alrededor de 1275 operaciones.
También tratar con envolver alrededor de 0/180 grados de coordenadas podría ser un desafío.
De todos modos, no quería dedicar todo un día a esto, incluso podría lidiar con una solución que NO tiene que ver con la condición general.
Con la esperanza de que haya un buen algoritmo para esto, en algún lugar ya puedo aparecer (probablemente tiene algún término técnico sofisticado).
También sería genial si hubiera un enfoque más eficiente que la fuerza bruta mirando hacia adelante.
Como mencioné en los comentarios, la mejor herramienta para consultar datos espaciales sería usar PostGIS.
Por ejemplo, PostGIS tiene el ST_validReason () para encontrar el problema con el polígono y un st_makevalid para solucionarlo, pero si esta no es una opción, crearía un servicio disponible para su script PHP con una biblioteca de python https://github.com/Toblerity/Shapely
http://toblerity.org/shapely/manual.html
La primera premisa de Shapely es que los programadores de Python deberían poder realizar operaciones de geometría de tipo PostGIS fuera de un RDBMS
Ciertamente, shapely
es una herramienta popular, y debería recibir ayuda futura con o gis.stackexchange.com de usuarios más experimentados
Creo que el problema que intentas resolver no es tan trivial como parece.
Así que realizaría los siguientes pasos:
1 Encuentra cómo hacerlo con forma.
Preguntas similares: la división del polígono que solo se intersecaba solo devolvió un polígono bien formado en Python
2 crear un servicio php simple que pasará los detalles de la consulta al script de Python
3 Shapely no impedirá la creación de un polígono no válido, pero se generarán excepciones cuando se utilicen. Básicamente, en tal excepción, llamaría al script desde el paso 1.
Si esto es solo para una consulta, solo usaría el software QGIS (importar puntos como CSV, crear una nueva capa de shapefile (de tipo polígono) y usar el complemento de edición de vértice numérico)
actualizar
Creo que el polígono debería ser arreglado por la herramienta que lo creó, de modo que, en este caso, debería ser un usuario. Tal vez solucione ese problema mirando desde un ángulo diferente y si la forma proviene del usuario y se dibuja en GoogleMap en su aplicación, es posible que no exista intersección durante el dibujo.
También se encuentra Dibujando un polígono (ordenando puntos y creando polígonos sin intersección)
Debido a que sus coordenadas son idénticas, se crea una anomalía en la forma del polígono: [-97.1788790, 49.9193990 ] y [-97.2035980, 49.9193990 ]. En su código elimine o cambie cualquiera de las coordenadas duplicadas,
"coordinates": [[
[-97.209091, 49.905691],
[-97.206345, 49.918072],
[-97.178879, 49.919399], // this line
[-97.165146, 49.907903],
[-97.164459, 49.892865],
[-97.180939, 49.889326],
[-97.197418, 49.895077],
[-97.200165, 49.902596],
[-97.203598, 49.919399], // and this one
[-97.216644, 49.928682],
[-97.244797, 49.927356],
[-97.255096, 49.913209],
[-97.209091, 49.905691]
]]