7

I let the users draw polygons and then I try to save them out to the SQL Server 2008 SQLGeography field, but it is giving me an error:

Error 24200: The specified input does not represent a valid geography instance.

I think the issue is because the polygon intersects itself and SQL doesn't accept this behavior. Is it possible to do a check in OpenLayers to see if the WKT from the polygon would be accepted by the SQLGeography.STGeomFromText function?

9

There are no built-in checks for this in OpenLayers, but it should be possible to implement one quite easily.

The Polygon class has a Components property which holds several LinearRings, the first ring beeing the outer ring and the consecutive ones (if any) represents holes.

To find self-intersections you could make a function that loops the induvidual points of each ring, forming linestrings and checking intersections.

I think an approach like this should work (this only checks if the outer ring is self-intersecting, but it should be quite easy to extend it to holes, just build segments from the holes and push to the segments array)

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));
4

The excellent Java Topology Suite has been/is being ported to Javascript:

https://github.com/bjornharrtell/jsts

you could try using its Geometry.isValid() method to test the polygon for correctness before submitting it to the server.

0

Don't know if you found an answer for this, but I found this link very helpful and it was a combination that worked for me. http://www.beginningspatial.com/fixing_invalid_geography_data

Hope it helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.