Wednesday, October 19, 2011

Ensure Correct Ring Orientation for SqlGeography

SqlGeography is very picky about the order of points when reading Well Known Text (WKT): if your WKT points aren’t just so, the de-serialization will throw something like this:

A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
Microsoft.SqlServer.Types.GLArgumentException: 24205: The specified input does not represent a valid geography instance because it exceeds a single hemisphere. Each geography instance must fit inside a single hemisphere. A common reason for this error is that a polygon has the wrong ring orientation.

Luckily, there are smarter people in the world than me.  Here’s a post on how to use T-SQL to ensure correct ring orientation.  Here’s how I do it using Microsoft.SqlServer.Types in C#:

// a helper SqlGeometry, which isn't picky about ring orientation
var geometryHelper =
SqlGeometry.STGeomFromText(wkt.ToSqlChars(), srid).MakeValid();

// STUnion will automagically correct any bad ring orientation
var validGeom =
geometryHelper.STUnion(geometryHelper.STStartPoint());

// use the validGeom with correct ring orientation to
// create a SqlGeography.
var validGeography =
SqlGeography.STGeomFromText(validGeom.STAsText(), srid);

2 comments:

  1. 'Microsoft.SqlServer.Types.SqlGeography' could be found (are you missing a using directive or an assembly reference?) C:\Users\amr abdelwahab\Documents\Visual Studio 2012\Projects\Allegro Web\MvcWebRoleCore\Controllers\ServiceProviderController.cs 173 14 MvcWebRoleCore


    That's what I get when I try adding makevalid

    ReplyDelete
  2. Error 18 'Microsoft.SqlServer.Types.SqlGeography' does not contain a definition for 'MakeValid' and no extension method 'MakeValid' accepting a first argument of type 'Microsoft.SqlServer.Types.SqlGeography' could be found (are you missing a using directive or an assembly reference?) C:\Users\amr abdelwahab\Documents\Visual Studio 2012\Projects\Allegro Web\MvcWebRoleCore\Controllers\ServiceProviderController.cs 173 14 MvcWebRoleCore

    ReplyDelete