SpatialDB Advisor
Ever needed to extract a textual description of all geometry types in a single geometry/geography in SQL Server 2008?
Recently I had cause to do so and created the following function that implements this need.
/*********************************************************************************
** @function : Geometry_Type
** @precis : Returns geometry type of passed in geometry as string.
** @description : Returns list of geometry types (from OGC STGeometryType function)
** that describe the contents of the passed in geometry.
** Any GeometryCollection is "exploded" to examine the geometry types
** within it.
** Geography objects can be processed by converting to geometry using
** dbo.toGeometry() function.
** @example : select dbo.geometry_type(geometry::STGeomFromText('POINT(0 1 2)',0));
** @param : p_geom : the geometry object to be processed.
** @param_type : p_geom : geometry
** @history : Simon Greener, The Spatial DB Advisor, September 2009
** @copyright : Licensed under a Creative Commons Attribution-Share Alike 2.5 Australia License.
** (http://creativecommons.org/licenses/by-sa/2.5/au/)
**/
Now let’s test it against a selection of all possible geometry types
select dbo.geometry_type(geometry::STGeomFromText('
POINT(0 1 2)',0)) as gtype
union all select dbo.geometry_type(geometry::STGeomFromText('
MULTIPOINT((0 0 0),
(1 1 1),
(2 2 2),
(3 3 3))',0)) as gtype
union all select dbo.geometry_type(geometry::STGeomFromText('
LINESTRING(0 0, 1 1)',0)) as gtype
union all select dbo.geometry_type(geometry::STGeomFromText('
MULTILINESTRING(
(0 0,1 1,1 2),
(2 3,3 2,5 4))',0)) as gtype
union all select dbo.geometry_type(geometry::STGeomFromText('
POLYGON(
(326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0),
(326500.0 5455500.0,326550.0 5455200.0,326450.0 5455200.0,326500.0 5455500.0))',0)) as gtype
union all SELECT dbo.geometry_type(geometry::STGeomFromText('
MULTIPOLYGON(
((326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0),
(326500.0 5455500.0,326550.0 5455200.0,326450.0 5455200.0,326500.0 5455500.0)),
((321000.0 5450000.0,322000.0 5450000.0,321500.0 5451000.0,321000.0 5450000.0)))',0)) as gtype
union all select dbo.geometry_type(geometry::STGeomFromText('
GEOMETRYCOLLECTION(
POINT(2 3 4),
LINESTRING(2 3 4,3 4 5),
POLYGON((326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0)),
POINT(4 5))',0));
| gtype |
|---|
| Point |
| MultiPoint |
| LineString |
| MultiLineString |
| Polygon |
| MultiPolygon |
| GeometryCollection:Point:LineString:Polygon |
But what if I want to create a single string that describes all the geometries in a particular table?
Here is one way to do this via XML aggregation.
WITH geometry_Types AS
(
SELECT distinct dbo.geometry_type(a.geom) as gtype
FROM (select geometry::STGeomFromText('
POINT(0 1 2)',0) as geom
union all select geometry::STGeomFromText('
MULTIPOINT((0 0 0),
(1 1 1),
(2 2 2),
(3 3 3))',0) as geom
union all select geometry::STGeomFromText('
LINESTRING(0 0, 1 1)',0) as geom
union all select geometry::STGeomFromText('
MULTILINESTRING(
(0 0,1 1,1 2),
(2 3,3 2,5 4))',0) as geom
union all select geometry::STGeomFromText('
POLYGON(
(326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0),
(326500.0 5455500.0,326550.0 5455200.0,326450.0 5455200.0,326500.0 5455500.0))',0) as geom
union all SELECT geometry::STGeomFromText('
MULTIPOLYGON(
((326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0),
(326500.0 5455500.0,326550.0 5455200.0,326450.0 5455200.0,326500.0 5455500.0)),
((321000.0 5450000.0,322000.0 5450000.0,321500.0 5451000.0,321000.0 5450000.0)))',0) as geom
union all select geometry::STGeomFromText('
GEOMETRYCOLLECTION(
POINT(2 3 4),
LINESTRING(2 3 4,3 4 5),
POLYGON((326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0)),
POINT(4 5))',0) as geom
) a
)
SELECT (STUFF((SELECT DISTINCT ':' + a.gtype
FROM geometry_types a
ORDER BY ':' + a.gtype
FOR XML PATH(''), TYPE, ROOT).value('root[1]','nvarchar(max)'),1,1,'')
) as GeometryTypes;
| GeometryTypes |
|---|
| GeometryCollection:Point:LineString:Polygon:LineString:MultiLineString:MultiPoint:MultiPolygon:Point:Polygon |
Notice how the list is not unique. Here is one method of making it unique.
WITH geometries AS
(
select geometry::STGeomFromText('
POINT(0 1 2)',0) as geom
union all select geometry::STGeomFromText('
MULTIPOINT((0 0 0),
(1 1 1),
(2 2 2),
(3 3 3))',0) as geom
union all select geometry::STGeomFromText('
LINESTRING(0 0, 1 1)',0) as geom
union all select geometry::STGeomFromText('
MULTILINESTRING(
(0 0,1 1,1 2),
(2 3,3 2,5 4))',0) as geom
union all select geometry::STGeomFromText('
POLYGON(
(326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0),
(326500.0 5455500.0,326550.0 5455200.0,326450.0 5455200.0,326500.0 5455500.0))',0) as geom
union all SELECT geometry::STGeomFromText('
MULTIPOLYGON(
((326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0),
(326500.0 5455500.0,326550.0 5455200.0,326450.0 5455200.0,326500.0 5455500.0)),
((321000.0 5450000.0,322000.0 5450000.0,321500.0 5451000.0,321000.0 5450000.0)))',0) as geom
union all select geometry::STGeomFromText('
GEOMETRYCOLLECTION(
POINT(2 3 4),
LINESTRING(2 3 4,3 4 5),
POLYGON((326000.0 5455000.0,327000.0 5455000.0,326500.0 5456000.0,326000.0 5455000.0)),
POINT(4 5))',0) as geom
)
SELECT (STUFF((SELECT DISTINCT ':' + a.gtype
FROM ( select distinct t.token as gtype
from geometries a
cross apply
dbo.Tokenizer(dbo.geometry_type(a.geom),':') as t
) a
ORDER BY ':' + a.gtype
FOR XML PATH(''), TYPE, ROOT).value('root[1]','nvarchar(max)'),1,1,'')
) as GeometryTypes;
| GeometryTypes |
|---|
| GeometryCollection:LineString:MultiLineString:MultiPoint:MultiPolygon:Point:Polygon |
Finally, show how we can use the function with geography type data.
select dbo.Geometry_Type(
dbo.MBR2GEOMETRY(147,-44,148,-43,4326).STDifference(
dbo.MBR2GEOMETRY(147.4,-43.6,147.6,-43.2,4326) ).STUnion(
dbo.MBR2GEOMETRY(150,-44,151,-43,4326) ) ) as geogtypes;
| geogtypes |
|---|
| MultiPolygon |
I hope this function is useful to someone.


















<<Vectorising geometry objects in SQL Server 2008 >>Checking is a column in a table or a view is of type geometry or geography