7 votos

Determinar si un polígono se interseca a sí mismo en OpenLayers

Dejo que los usuarios dibujen polígonos y luego intento guardarlos en el campo SQLGeography de SQL Server 2008, pero me da un error:

Error 24200: La entrada especificada no representa una instancia geográfica válida.

Creo que el problema es porque el polígono se interseca a sí mismo y SQL no acepta este comportamiento. ¿Es posible hacer una comprobación en OpenLayers para ver si el WKT del polígono sería aceptado por la función SQLGeography.STGeomFromText?

9voto

pufferfish Puntos 679

No hay controles incorporados para esto en OpenLayers, pero debería ser posible implementar uno con bastante facilidad.

El Clase de polígono tiene una propiedad Componentes que contiene varios LinearRings El primer anillo es el exterior y los siguientes (si los hay) representan los agujeros.

Para encontrar auto-intersecciones podrías hacer una función que haga un bucle en los puntos induviduales de cada anillo, formando cadenas de líneas y comprobando las intersecciones.

Creo que un enfoque como este debería funcionar (esto sólo comprueba si el anillo exterior es auto-intersectivo, pero debería ser bastante fácil extenderlo a los agujeros, sólo hay que construir segmentos a partir de los agujeros y empujar a la matriz de segmentos)

var format = new OpenLayers.Format.WKT();

var f1=format.read("POLYGON(1 1, 4 1, 4 4, 1 4, 2 5, 1 1)");
var f2=format.read("POLYGON(1 1, 4 1, 4 4, 1 4, 1 1)");

function checkSelfIntersection(polygon){
    console.log(polygon);
    if(polygon.CLASS_NAME=="OpenLayers.Geometry.Polygon"){
        //checking only outer ring
        var outer = polygon.components[0].components;           
        var segments = [];
        for(var i=1;i<outer.length;i++){
            var segment= new OpenLayers.Geometry.LineString([outer[i-1].clone(),outer  [i].clone()]);
            segments.push(segment);               
        }   
        for(var j=0;j<segments.length;j++){    
            if(segmentIntersects(segments[j],segments)){
               return true;
            }
        }                     
    }    
    return false;
}

function segmentIntersects(segment,segments){
    for(var i=0;i<segments.length;i++){
        if(!segments[i].equals(segment)){
            if(segments[i].intersects(segment) && !startOrStopEquals(segments[i],segment)){
                return true;
           }            
       }    
    }
    return false;    
}    

function startOrStopEquals(segment1,segment2){

    if(segment1.components[0].equals(segment2.components[0])){
        return true;
    }
    if(segment1.components[0].equals(segment2.components[1])){
        return true;
    }
    if(segment1.components[1].equals(segment2.components[0])){
        return true;
    }
    if(segment1.components[1].equals(segment2.components[1])){
        return true;
    }
    return false;
}

console.log(checkSelfIntersection(f1.geometry));
console.log(checkSelfIntersection(f2.geometry));

2voto

Celso Puntos 66

El excelente Java Topology Suite ha sido/está siendo portado a Javascript:

https://github.com/bjornharrtell/jsts

puedes intentar usar su Geometry.isValid() para comprobar que el polígono es correcto antes de enviarlo al servidor.

0voto

Divi Puntos 202

No sé si has encontrado una respuesta para esto, pero encontré este enlace muy útil y fue una combinación que me funcionó. http://www.beginningspatial.com/fixing_invalid_geography_data

Espero que sea de ayuda

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X