다음을 통해 공유


The Unexpected Too-Large Polygon

Hi Folks,

I recently got contacted via email with the following problem:

...

I have 2 complex polygons, representing district boundaries.  The polygons look correct, but I'm getting exceptions when I try to create the type.

I've attached the wkt polygons to the email.

These polygons are stored in a table, but I've tried it without the table and get the same result.

Here's the sql I'm trying to execute:

declare @g geography;
set @g = geography::STPolyFromText(@wkt, 4268)
select @g.ToString()

where @wkt is replaced by the correct polygon string.

...

Now, I should point out that this is a very nice error report.  They've told me what their data is, they included their data, and they told me very clearly what they're trying to do.  (Perhaps knowing what version they're using would good, but I'm getting picky.)

But here's the kicker that saved me any debugging:

...
Here is the error message I receive:

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.
Microsoft.SqlServer.Types.GLArgumentException:
   at Microsoft.SqlServer.Types.GLNativeMethods.ThrowExceptionForHr(GL_HResult errorCode)
   at Microsoft.SqlServer.Types.GLNativeMethods.GeodeticIsValid(GeometryData g)
   at Microsoft.SqlServer.Types.SqlGeography.IsValidExpensive()
   at Microsoft.SqlServer.Types.SqlGeography.ConstructGeographyFromUserInput(GeometryData g, Int32 srid)
   at Microsoft.SqlServer.Types.SqlGeography.STPolyFromText(SqlChars polygonTaggedText, Int32 srid)

I looked at all the nodes, and they are all in the same hemisphere, so I'm a little confused with what might be going on.
...

So, what's going on?  Ring ordering.

I've posted on this before, but let's recap.  On a round Earth, defining a polygon by a ring is ambiguous.  Consider the polygon defined by a ring around the equator: does this describe the northern or southern hemisphere?  A small ring could describe either, say, a small island in a large ocean, or the large ocean itself.

To get out of this pickle, we disambiguate with a standard trick: we take ring orientation into account.  We simply define the left side of the ring as it is drawn to be inside the polygon.

If we put this together with our current (unfortunate) limitation that we do not deal with objects that exceed a hemisphere, and it becomes clear what's going on.  While the polygon looks like it's nice and small, the rings are inverted, and so it's actually quite large.  We can't handle it: cue the exception.

I describe this hemisphere limitation as unfortunate, and it remains one of the biggest items the spatial team would like to fix up, but in this case it has actually helped catch an error.

I'll talk a bit more about our hemisphere limitation in a future post.  It's not quite as simple as we let on.

Cheers,
-Isaac

Comments

  • Anonymous
    May 03, 2008
    Hi Folks, In previous posts about our new geography type, I've discussed ring orientation and too-large

  • Anonymous
    December 11, 2008
    I get this error when trying to do the following. The targeted geometry is a census block - it doesn't span hemispheres. DECLARE @gem GEOMETRY SELECT @gem=Shape FROM ShapeTable WHERE Id=2361379 SELECT GEOGRAPHY::STGeomFromWKB(@gem.STAsBinary(),4326)

  • Anonymous
    December 11, 2008
    The comment has been removed

  • Anonymous
    December 11, 2008
    Isaac, Thanks for that! I made the modification: SELECT @gem=@gem.STUnion(@gem.STStartPoint()) and now the conversion to Geography type works. I suppose I'll have to do this to all the geometry data in my db now. I wonder why the ring orientation would be wrong - perhaps when I imported it? Thanks again, Ed