3. SQL Server Spatial Summary
OVERVIEW FEATURES
• 2 Spatial Data Types (CLR UDT) • 2D Vector Data Support
• Comprehensive set of Spatial Methods • Open Geospatial Consortium Simple
• High Performance Spatial Indexes Features for SQL compatible
• Spatial Industry Standards Support • Supported By Major GIS Vendors
• Spatial Library ESRI, Intergraph, Autodesk, Pitney Bowes, Safe, etc.
•Management Studio Integration • Standard feature in all SQL Server Editions
• Cloud-enabled • Support for very large spatial objects (2GB)
• Supported in SS Reporting Services
• Redistributable Spatial Library
DETAILS
• Geography data type for geodetic data
• Geometry data type for planar data
• Standard spatial methods
STIntersects, STBuffer, STLength, STArea, etc.
• Standard spatial format support (WKT, WBK, GML)
• Multiple spatial indexes per column
• Multiple spatial columns per table
• Create new CLR-based spatial functions
with the Sink/Builder APIs
• SQL Azure Spatial support
• Support for circular (curve) spatial objects
• Support for full globe geography objects
• Optimized performance for the sphere Ed Katibah, SQL Server, July 1, 2008
4. 2 Spatial Datatypes
• Geography (Geodetic)
• Geometry (Planar)
Geography
• Ellipsoidal coordinate support only (e.g. WGS 84)
• Core set of geospatial methods
• No OGC/ISO standards compliance (though many standards components are there)
• Geospatial index
• Designed as a simple, straight-forward geospatial implementation
Geometry
• Planar coordinate support only (georeferenced and non-georeferenced)
• Complete set of spatial methods
• OGC/ISO standards compliance (OGC SFS v1.1, ISO 19125)
• Spatial index
• Comprehensive spatial/geospatial offering supporting 2D planimetric
applications
6. Spatial Data Type Support
Spatial Methods
• Retrieving Properties of Geometry Objects
• Constructing Geometry Objects
• Returning WKT, WKB and GML
• Querying Validity, Instance Type, and Geometry Collection
Information
• Determining the Relationship between Two Geometries
• Creating New Geometries
Spatial Indexes
• 4 Spatial indexes, two for geometry and two for geography
18. Auto Grid Spatial Index
Index Construction
CREATE SPATIAL INDEX idxGeog CREATE SPATIAL INDEX idxGeom
ON table(geography column) ON table(geometry column)
USING GEOGRAPHY_AUTO_GRID; USING GEOMETRY_AUTO_GRID;
or or
CREATE SPATIAL INDEX idxGeog CREATE SPATIAL INDEX idxGeom
ON table(geography column) ON table(geometry column)
USING GEOGRAPHY_AUTO_GRID USING GEOMETRY_AUTO_GRID
WITH (CELLS_PER_OBJECT = 32); WITH (CELLS_PER_OBJECT = 32);
Geography Type: Geometry Type:
Default Cells per Object: 12 Default Cells per Object: 8
19. New Spatial Index Hint
SPATIAL_WINDOW_MAX_CELLS
Fine tuning at runtime for spatial indexes
SELECT *
FROM table t
WITH (SPATIAL_WINDOW_MAX_CELLS=32)
WHERE t.geom.STIntersects(@window)=1;
The default value is 512 for geometry and
768 for geography. In SQL Server 2008, this
value was hardcoded at 1024.
21. • Optimal value (theoretical) is
somewhere between two extremes
Default values: Time needed to
512 - Geometry AUTO grid process false positives
768 - Geography AUTO grid
1024 - MANUAL grids
22. Spatial Index Compression
CREATE SPATIAL INDEX idxGeog
ON table(geography column)
USING GEOGRAPHY_GRID
WITH (
DATA_COMPRESSION = <page | row>
);
On the basis of internal tests, with compression:
• 40%-50% smaller than uncompressed counterparts
• 5%-10% performance overhead for small indexes
• For large indexes, performance improvements are observed
26. LINESTRING (0 50, 90 50, 180 50,
270 50, 0 50)
Linestring segments in the
geography type define the
minimum distance path on the
underlying ellipsoid.
CIRCULARSTRING (0 50, 90 50,
180 50, 270 50, 0 50)
Circularstring segments in the
geography type define a circular
path. A good example is a latitude
parallel.
27. Circular Arcs
Geography Type Considerations
CIRCULARSTRING
(0 50, 90 50, 180 50, 270 50, 0 50)
If a circular linestring is closed, a
curve polygon can be created
CURVEPOLYGON (CIRCULARSTRING
(0 50, 90 50, 180 50, 270 50, 0 50))
Coordinate pair order is important
for the geography type. This set
of coordinates is ordered according
to the “left foot rule” for exterior
rings.
28. New Methods for Circular Arcs
BufferWithCurves()
This method will construct the
resulting polygon with circular
arcs, often resulting in a
dramatically smaller spatial
object.
DECLARE @g GEOGRAPHY =
GEOGRAPHY::STGeomFromText('CIRCULARSTRING(0 50,
45 50, 90 50)',4326)
DECLARE @b GEOGRAPHY =
@g.BufferWithCurves(500000)
SELECT @b.STNumPoints()
--Number of vertices: 11
DECLARE @g GEOGRAPHY =
GEOGRAPHY::STGeomFromText('CIRCULARSTRING(0 50,
45 50, 90 50)',4326)
DECLARE @b GEOGRAPHY = @g.STBuffer(500000)
SELECT @b.STNumPoints()
--Number of vertices: 257
29. New Methods for Circular Arcs
continued…
• STNumCurves()
Returns the number of curves in an object
• STCurveN()
Used for iteration through the list of the edges
• STCurveToLine()
Convert curve components to a linestring
• CurveToLineWithTolerance()
Same as above but with user specific tolerance
30. Existing Methods And Circular Arcs
All existing method work on circular arcs
STIntersects() example
31. New and Updated Methods and Aggregates for
all Types
ShortestLineTo();
returns a linestring which represents the
shortest distance between 2 objects
HasZ, HasM
[boolean] returns 0 or 1 if object has Z or
M-value components
32. New and Updated Methods and Aggregates for all
Types
UnionAggregate()
EnvelopeAggregate()
CollectionAggregate()
ConvexHullAggregate()
33. The following aggregate examples will use this core data
SELECT geog FROM Counties
WHERE name_1 = 'Washington„
--Results: 39 rows, 1 for each county in the State of Washington
All aggregates are static methods which
work for either the Geography or
the Geometry data types. For instance,
consider the geography aggregate:
Geography::UnionAggregate(geog)
and its counterpart for geometry:
Geometry::UnionAggregate(geom)
34. Definition: Combines multiple spatial objects into a single spatial object,
removing interior boundaries, where applicable.
SELECT Geography::UnionAggregate(geog) FROM Counties
WHERE name_1 = 'Washington';
35. Definition: Returns a bounding circular object as a CurvePolygon which encloses
one or more spatial objects.
SELECT Geography::EnvelopeAggregate(geog).STCurveToLine() FROM Counties
WHERE name_1 = 'Washington';
Notes: STCurveToLine() method employed to assist in circular object rendering with visualization
programs which do not support curve objects.
36. Definition: Returns a 5 point polygon (rectangle) which encloses one or
more spatial objects.
SELECT Geometry::EnvelopeAggregate(geom) FROM Counties
WHERE name_1 = 'Washington';
Notes: County input objects are in a US-wide Albers
projection which accounts for the apparent data
rotation.
37. Definition: Returns a geometry collection with one geometry part for each sp
object(s) in the selection set.
SELECT Geography::CollectionAggregate(geog) FROM Counties
WHERE name_1 = 'Washington';
Notes: Unlike the UnionAggregate, adjoining
interior boundaries are not removed for polygons
38. Definition: Returns a convex hull polygon which encloses one or more spatial
objects.
SELECT Geography::ConvexHullAggregate(geog) FROM Counties
WHERE name_1 = 'Washington';
41. • STLength()
Now works on both valid and invalid linestrings; STLength now
works on invalid linestrings. Typically a linestring is invalid due to
overlapping segment caused by anomalies such as inaccurate GPS
measurements.
• MinDbCompatibilityLevel()
Method used for backward compatibility; indicates if spatial
objects can be recognized by SQL Server 2008 and SQL Server
2008 R2.
• IsValidDetailed()
Provides commentary on what is wrong with invalid objects
42. 24400: Valid
24401: Not valid, reason unknown.
24402: Not valid because point ({0}) is an isolated point, which is not valid in this type of object.
24403: Not valid because some pair of polygon edges overlap.
24404: Not valid because polygon ring ({0}) intersects itself or some other ring.
24405: Not valid because some polygon ring intersects itself or some other ring.
24406: Not valid because curve ({0}) degenerates to a point.
24407: Not valid because polygon ring ({0}) collapses to a line at point ({1}).
24408: Not valid because polygon ring ({0}) is not closed.
24409: Not valid because some portion of polygon ring ({0}) lies in the interior of a polygon.
24410: Not valid because ring ({0}) is the first ring in a polygon of which it is not the exterior ring.
24411: Not valid because ring ({0}) lies outside the exterior ring ({1}) of its polygon.
24412: Not valid because the interior of a polygon with rings ({0}) and ({1}) is not connected.
24413: Not valid because of two overlapping edges in curve ({0}).
24414: Not valid because an edge of curve ({0}) overlaps an edge of curve ({1}).
24415: Not valid some polygon has an invalid ring structure.
24416: Not valid because in curve ({0}) the edge that starts at point ({1}) is either a line or a degenerate arc with antipodal endpoints.
43. declare @p geography = 'Polygon((2 2, 4 4, 4 2, 2 4, 2 2))'
select @p.IsValidDetailed()
--Results: 24409: Not valid because some portion of polygon ring (1)
-- lies in the interior of a polygon.
44. All constructions and relations are now done with 48 bits of precision in
Denali, compared to 27 bits used in SQL Server 2008 and 2008 R2.
For example, consider the following coordinate which was processed using the
STUnion() method in SQL Server 2008
-82.339026 29.661245 -82.339025999885052 29.662144999951124
In Denali, the greater numerical precision typically maintains the precision of the
original coordinates. Here is the result of the same STUnion() method in Denali, as
above
-82.339026 29.661245 82.339026 29.661245
47. Full Globe
Geography Type Enhancement
CURVEPOLYGON
(CIRCULARSTRING (0 50, 90 50,
180 50, 270 50, 0 50))
Coordinate pair order is important
for the geography type. This set
of coordinates is ordered according
to the “left foot rule” for exterior
rings.
What happens if the coordinates
defining the exterior ring are
reversed?
48. Full Globe
Geography Type Enhancement
CURVEPOLYGON
(CIRCULARSTRING (0 50, 90 50,
180 50, 270 50, 0 50))
If we reverse the order of the
coordinate pairs, using the
“right foot rule” for interior
rings, this curve polygon now
represents “the rest of the globe”.
CURVEPOLYGON
(CIRCULARSTRING (0 50, 270 50,
180 50, 90 50, 0 50))
56. On March 20, 2010, the trimaran, Groupama 3,
became the fastest boat to circumnavigate the
Earth non-stop, ever (including power boats)…
in 48 days, 7 hours and 44 minutes…
…and of course, it‟s GPS-equipped…
57.
58.
59.
60.
61. DECLARE @t GEOGRAPHY = (SELECT Track FROM Groupama_Track7)
SELECT TOP 16 CNTRY_NAME, SOVEREIGN,
POP_CNTRY, @t.STDistance(Geography) AS [DISTANCE FROM TRACK]
FROM Countries ORDER BY @t.STDistance(Geography)
CNTRY_NAME SOVEREIGN POP_CNTRY DISTANCE FROM TRACK
France France 57757060 0
New Zealand New Zealand 3528197 7115.41609170632
Chile Chile 13772710 15409.5690252515
Spain Spain 39267780 37144.5519830663
Portugal Portugal 9625516 57621.7065806319
Argentina Argentina 33796870 106198.966899358
United Kingdom United Kingdom 56420180 158636.063519451
Cape Verde Cape Verde 413573 165226.105053976
Guernsey United Kingdom 62920 177654.285742873
Jersey United Kingdom 87848 189169.527892158
Brazil Brazil 151525400 205920.063533954
Falkland Is. United Kingdom 2136 237487.364201179
Fr. So. & Ant. Lands France -99999 397707.475465133
Ireland Ireland 5015975 416683.669375291
Australia Australia 17827520 418237.701906367
South Africa South Africa 40634126 430605.825881581
62. New Geography Methods
ReorientObject()
• This method will reverse the
order of coordinates which
define polygon rings.
• This method is a no-op on
line strings, circular arcs and
points.
• This method does not work
with the geometry type.
65. SELECT TOP(5) *
FROM Restaurants r
WHERE r.type = ‘Italian’
AND r.position.STDistance(@me) IS NOT NULL
ORDER BY r.position.STDistance(@me)
It can also be expressed with limited maximum distance
SELECT TOP(5) *
FROM Restaurants r
WHERE r.type = ‘Italian’
AND r.position.STDistance(@me) < @max_range
ORDER BY r.position.STDistance(@me)
68. Two new helper methods are available:
• sp_help_spatial_geography_histogram
• sp_help_spatial_geometry_histogram
They can be used for investigating spatial index efficiency or analyzing spatial
data in general. The histograms could be also shown on a SSMS map.
The data can be used for external visualization:
69. •
CREATE TABLE location (
id int primary key,
x float(max),
y float(max),
range float(max),
geom as
geometry::Point(x, y, 0)
.STBuffer(range) PERSISTED );
•
70. Client Side Library Changes
New sink interfaces are available IGeometrySink110 and
IGeographySink110. They should be used in the future. They must be
used for objects incompatible with SQL Server 2008:
• Objects bigger than a logical hemisphere
• Objects with circular arcs
• Invalid geography
However, the old sinks will continue to work for SQL Server 2008
compatible objects.
Geometry and Geography builders (SqlGeometryBuilder and
SqlGeographyBuilder) now support circular arc constructions.
New method “Deserialize” is added on the client library to both types.
88. •
USE Sample_USA;
GO
--Union Aggregates - Geography
SELECT Geography::UnionAggregate(geog) FROM Counties
WHERE NAME_1 = 'Washington';
GO
--Union Aggregates - Geometry
SELECT Geometry::UnionAggregate(geom) FROM Counties
WHERE NAME_1 = 'Washington';
GO
89. •
USE Sample_USA;
GO
--Envelope Aggregate - Geography
SELECT Geography::EnvelopeAggregate(geog) FROM Counties
WHERE NAME_1 = 'Washington'
UNION ALL
SELECT geog from Counties
WHERE NAME_1 = 'Washington'
GO
--Envelope Aggregate - Geometry (why are the county spatial objects "rotated")
SELECT Geometry::EnvelopeAggregate(geom) FROM Counties
WHERE NAME_1 = 'Washington'
UNION ALL
SELECT geom from Counties
WHERE NAME_1 = 'Washington'
GO
90. •
USE Sample_USA;
GO
--Collection Aggregate
SELECT Geography::CollectionAggregate(geog) FROM Counties
WHERE NAME_1 = 'Washington';
GO
--Is it really a single object - if so, how many parts does it have?
DECLARE @a GEOGRAPHY = (SELECT Geography::CollectionAggregate(geog)
FROM Counties
WHERE NAME_1 = 'Washington');
SELECT @a.STNumGeometries();
GO
--Results: 39
--Coincidentally, this is exactly the same number of counties in the State of
Washington ;-)
SELECT COUNT(*) FROM Counties
WHERE NAME_1 = 'Washington';
GO
91. •
USE Sample_USA;
GO
--Convex Hull - Geography
SELECT Geography::ConvexHullAggregate(geog) FROM Counties
WHERE NAME_1 = 'Washington'
UNION ALL
SELECT geog from Counties
WHERE NAME_1 = 'Washington„
GO
--Convex Hull - Geometry
SELECT Geometry::ConvexHullAggregate(geom) FROM Counties
WHERE NAME_1 = 'Washington'
UNION ALL
SELECT geom from Counties
WHERE NAME_1 = 'Washington„
GO
92. •
DECLARE @p geography = 'Polygon((2 2, 4 4, 4 2, 2 4, 2 2))'
SELECT @p.IsValidDetailed();
GO
--Results: 24409: Not valid because some portion of polygon ring (1)
-- lies in the interior of a polygon.
93. •
--Invalid LineStrings - new behavior
DECLARE @line geometry = 'LineString(1 1, 2.1 1, 2.0 1, 4 1)'
SELECT @line.STIsValid();
GO
--Results: 0 (invalid)
DECLARE @line geometry = 'LineString(1 1, 2.1 1, 2.0 1, 4 1)'
SELECT @line.IsValidDetailed();
GO
--Results: 24413: Not valid because of two overlapping edges in curve (1).
94. •
--You can still perform metric operations
DECLARE @line geometry = 'LineString(1 1, 2.1 1, 2.0 1, 4 1)'
SELECT @line.STLength();
GO
--Results: 3.2
--You cannot perform other operations, however
DECLARE @line geometry = 'LineString(1 1, 2.1 1, 2.0 1, 4 1)'
SELECT @line.STBuffer(.5);
GO
--Results: 24144: This operation cannot be completed because the instance is not
valid.
95. •
USE World;
GO
DECLARE @g GEOGRAPHY
SET @g = GEOGRAPHY::STGeomFromText('
CURVEPOLYGON(
CIRCULARSTRING(0 50, 90 50, 180 50, 270 50, 0 50)
)
',4326);
SELECT @g
UNION ALL
SELECT geography from World.dbo.Countries
GO
96. •
USE World;
GO
DECLARE @g GEOGRAPHY
SET @g = GEOGRAPHY::STGeomFromText('
CURVEPOLYGON(
CIRCULARSTRING(0 50, 90 50, 180 50, 270 50, 0 50)
)
',4326);
SELECT @g.ReorientObject()
UNION ALL
SELECT geography from World.dbo.Countries
GO
97. •
--Buffer
DECLARE @g GEOGRAPHY =
GEOGRAPHY::STGeomFromText('CIRCULARSTRING(0 50, 45 50, 90 50)',4326)
DECLARE @b GEOGRAPHY = @g.STBuffer(500000)
SELECT @b --.STNumPoints()
UNION ALL
SELECT geography from World.dbo.Countries
GO
--Number of vertices: 257
--BufferWithCurves
DECLARE @g GEOGRAPHY =
GEOGRAPHY::STGeomFromText('CIRCULARSTRING(0 50, 45 50, 90 50)',4326)
DECLARE @b GEOGRAPHY = @g.BufferWithCurves(500000)
SELECT @b --.STNumPoints()
UNION ALL
SELECT geography from World.dbo.Countries
GO
--Number of vertices: 11