Working with Geography Data
The GEOGRAPHY data type is also implemented as a .NET common language runtime data type in SQL Server. Unlike the GEOMETRY data type in which locations are defined in terms of X and Y coordinates that can conceivably extend to infinity, the GEOGRAPHY
type represents data in a round-earth coordinate system. Whereas flat
models do not “wrap around,” the round-earth coordinate system does wrap
around such that if you start at a point on the globe and continue in
one direction, you eventually return to the starting point.
Because defining points on a ball using X and Y is not very practical, the GEOGRAPHY data type instead defines points using angles. The SQL Server GEOGRAPHY
data type stores ellipsoidal (round-earth) data as GPS latitude and
longitude coordinates. Longitude represents the horizontal angle and
ranges from -180 degrees to 180 degrees, and latitude represents the
vertical angle and ranges from -90 degrees to 90 degrees.
The GEOGRAPHY data type provides similar built-in methods as the GEOMETRY data type that you can use to create, validate, and query geography instances.
To assign a value to a geography column or variable, you can use the STGeogFromText methods to parse the parse geometry data provided in a valid WKT syntax into a valid geography value:
Declare @geog GEOGRAPHY
Declare @geog2 GEOGRAPHY
SET @geog =
geography::STGeomFromText('LINESTRING(-122.360 47.656,
-122.343 47.656)', 4326)
SET @geog2 =
geography::STGeomFromText('POLYGON((-122.358 47.653,
-122.348 47.649,
-122.348 47.658,
-122.358 47.658,
-122.358 47.653))', 4326)
As with the GEOMETRY data type, you can also use the STLineFromText static method that accepts only valid LINESTRINGS as input, or you can take advantage of the support for implicit conversion of WKT strings:
DECLARE @geog GEOGRAPHY
SET @geog = Geography::STLineFromText('LINESTRING (-122.360 47.656,
-122.343 47.656)', 4326)
set @geog = Geography::Parse('LINESTRING (-122.360 47.656,
-122.343 47.656)')
set @geog = 'LINESTRING (-122.360 47.656, -122.343 47.656)'
The following code uses the STLength() and STArea() methods to return the length of the LINESTRING:
DECLARE @geom GEOMETRY
SET @geom = geometry::STLineFromText('LINESTRING (100 100, 20 180, 180 180)', 0)
select @geom.STLength() as "Length"
go
Length
----------------------
273.137084989848
The preceding examples use local variables in a batch. You also can declare columns in a table using the geography data type, and you can use the instance properties and methods against the columns as well:
CREATE TABLE #geog
( id int IDENTITY (1,1),
GeogCol1 GEOGRAPHY,
GeogCol2 AS GeogCol1.STAsText() );
GO
INSERT INTO #geog (GeogCol1)
VALUES (geography::STGeomFromText
('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326));
INSERT INTO #geog (GeogCol1)
VALUES (geography::STGeomFromText
('POLYGON((-122.358 47.653,
-122.348 47.649,
-122.348 47.658,
-122.358 47.658,
-122.358 47.653))', 4326));
GO
DECLARE @geog1 GEOGRAPHY;
DECLARE @geog2 GEOGRAPHY;
DECLARE @result GEOGRAPHY;
SELECT @geog1 = GeogCol1 FROM #geog WHERE id = 1;
SELECT @geog2 = GeogCol1 FROM #geog WHERE id = 2;
SELECT @result = @geog1.STIntersection(@geog2);
SELECT Intersection = @result.STAsText();
go
Intersection
-------------------------------------------------
-----------------------------------------
LINESTRING (-122.3479999999668 47.656000260658459
, -122.35799999998773 47.656000130309728)