The CompoundCurve geometry in SQL Server 11 (Denali)

In my last post, I looked at the CircularString geometry introduced in SQL Server Denali, which allows you to define circular curve segments between points in a series, with each circular arc segment defined by a  anchor point between the two endpoints.

In this post, I’ll look at another new geometry type – the CompoundCurve. Whereas the LineString defines a one dimensional geometry by linear interpolation between a series of points, and the CircularString uses circular interpolation, the CompoundCurve can include a mixture of both of these types.

Here’s the WKT syntax for a CompoundCurve consisting of two line segments and two circular arc segments. Notice that circular arc segments within the curve must be prefixed by CIRCULARSTRING, whereas linear segments do not require (and, in fact, must not have) the corresponding LINESTRING keyword.

DECLARE @CompoundCurve geometry = 'COMPOUNDCURVE((5 3, 5 13), CIRCULARSTRING(5 13, 7 15, 9 13), (9 13, 9 3), CIRCULARSTRING(9 3, 7 1, 5 3))'

image

What’s interesting is that we don’t actually need to use the CompoundCurve to define this geometry – the CircularString geometry alone can contain a mixture of curved and straight edges: for straight line edges, the anchor point simply needs to lie on the straight line between the start and end point. We therefore could create exactly the same geometry using the CircularString by defining one additional anchor point on each of the straight edge sides as follows:

DECLARE @CircularString geometry = 'CIRCULARSTRING(5 3, 5 8, 5 13, 7 15, 9 13, 9 8, 9 3, 7 1, 5 3)';

image

In fact, as stated earlier, the CompoundCurve is much like a GeometryCollection containing a mixture of LineStrings and CircularStrings. We could therefore also define this same geometry as follows:

DECLARE @GeometryCollection geometry = 'GEOMETRYCOLLECTION(LINESTRING(5 3, 5 13), CIRCULARSTRING(5 13, 7 15, 9 13), LINESTRING(9 13, 9 3), CIRCULARSTRING(9 3, 7 1, 5 3))';

All three of these instances contain exactly the same set of points, as can be demonstrated with the following code:

SELECT @CompoundCurve.STEquals(@CircularString);   -- returns 1 (true)
SELECT @CompoundCurve.STEquals(@GeometryCollection);  -- returns 1 (true)

You can also test the length of each instance:

SELECT @CompoundCurve.STLength();  --32.5663706143592
SELECT @CircularString.STLength();  --32.5663706143592
SELECT @GeometryCollection.STLength();  --32.5663706143592

(The two line segments are 10 units long, and the two circular arcs combined form a circle of radius 2 units. (10 * 2) + (2 * PI * 2) = 32.5663706143592)

So why would you ever want to use the CompoundCurve class? Well, although it provides no greater functionality than the two alternatives presented here, and represents exactly the same set of points, it does provide a more efficient way of representing that geometry, certainly in terms of storage space required. Comparing the size of each geometry in this example:

SELECT DATALENGTH(@CompoundCurve), -- 152
DATALENGTH(@CircularString),  --176
DATALENGTH(@GeometryCollection) --243

This is because the CompoundCurve doesn’t require the additional overhead of the GeometryCollection (which is capable of storing any type of geometry), nor the additional points required by the CircularString to define the straight line segments.

I don’t know if performing operations against the CompoundCurve would be significantly faster than the other two options but, in the absence of any other factors, it still seems to be the best choice in this situation.

About these ads
This entry was posted in Spatial, SQL Server and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s