GEOGRAPHY DATATYPES in SQL Server by jared nielsen linkedin.com/nielsendata
GEOGRAPHY vs GEOMETRY Geography Plots ellipsoidal Round Earth data using latitude, longitude and altitude* coordinates Geometry Plots polygonal, geometric and linear data using X, Y and Z* coordinates * not implemented well
Measuring the Earth Coordinates Longitude = X Latitude = Y Altitude = Z
Measuring the Earth Ranges Longitude = 0 to 360 Latitude = 90 to -90 Altitude = 0 to (ft)
World Geodetic System Global standards body that defines the coordinate systems for Earth The latest revision is WGS 84 - referred to as EPSG:4326 www.nga.mil
EPSG: 4326 This geodetic standard is specified in many geography datatype queries: UPDATE SQLDevelopers SET GeoPosition = geography:: Point(29.5786422, -95.2049992, 4326)
BASIC GIS CONCEPTS Well Known Text ESRI Shape and Data Sources
Well Known Text - WKT Type Example Convert to Spatial Point Point(x,y).STPointFromText() MultiPoint MultiPoint( (x,y), (x,y) ).STMPointFromText() LineString LineString( x y, x y, x y).stlinefromtext() MultiLineString MultiLineString( (x y, x y) (x y, x y) ).STMLineFromText() Polygon Polygon ( (x1 y1, x2 y2, x3 y3, x1 y1) ).STPolyFromText() MultiPolygon You get the idea Keep using those parenthesis.stmpolyfromtext() www.nga.mil
How LONG is your LAT? Sometimes you should use LON/LAT (WKT) Other times you need to use LAT/LON (SQL) LAT LON San Jacinto College = 29.578, -95.204 SET GeoPosition = geography:: STGeomFromText('POINT(-95.204 29.578)', 4326) SET GeoPosition = geography:: Point(29.578, -95.204, 4326)
Get Some Data Positions for the International Space Station: http://sscweb.gsfc.nasa.gov/cgi-bin/locator.cgi Global Country Maps: http://www.vdstech.com/world-data.aspx Zip Codes, School Districts, Demographics: http://www.data.gov Railroads, Rivers, Cities, Volcanoes: http://webgis.wr.usgs.gov/globalgis/datasets.htm
ESRI Shapefile Converters Convert ESRI Shapefiles to SQL Geography: http://www.sharpgis.net/page/shape2sql Queries SQL Geography to a Map: http://www.sharpgis.net/page/sqlspatial-query-tool ESRI Metadata Translation: http://resources.esri.com/help/9.3/arcgisengine/ java/gp_toolref/conversion_tools/ esri_metadata_translator_conversion_.htm
SQL SERVER SPATIAL Make a Table Load Data Query Spatial-ly
Making a Table CREATE TABLE dbo.issposition( Longitude decimal(18, 15) NULL, Latitude decimal(18, 15) NULL, Sampled datetime NULL, LocalTime nvarchar(50) NULL, GeoPosition geography NULL, GeomShape geometry NULL )
Loading Data INSERT INTO ISSPosition (Sampled, Longitude, Latitude, LocalTime) VALUES ('01/01/2015 00:00:00',-125.4,41,'15:38:18 ) Naturally I loaded more data one data point per minute from January 1 to present It turns out that the Space Station falls fast at 17,136 mph
Convert to Geography UPDATE ISSPosition SET GeoPosition = geography:: Point([Latitude], [Longitude], 4326) GO (note we are using the native SQL Point method so we keep LAT/LON)
Query our Data select top 180 * from dbo.issposition Not the most thrilling outcome Let s try the Spatial Results Tab
Spatial Results Tab select top 180 * from dbo.issposition Still not that exciting a bunch of dots
Space Station Orbit select top 180 * from dbo.issposition order by Sampled Now we are getting somewhere!
Comma Delimited Points DECLARE @ISSOrbitWKT nvarchar(max) SELECT @ISSOrbitWKT = STUFF((SELECT TOP 180 ',' + Convert(nvarchar(25),Longitude) + ' ' + Convert(nvarchar(25),Latitude) FROM dbo.issposition ORDER BY Sampled FOR XML PATH('')),1,1,'')
Convert Points to LineStrings DECLARE @ISSOrbit geography SET @ISSOrbit = geography::stlinefromtext('linestring(' +@ISSOrbitWKT+')',4326)
Space Station Orbit SELECT @ISSOrbit Now you have connected points in a linestring showing the orbit
Space Station Orbit CREATE TABLE CoolShapes( Name Nvarchar(100) NOT NULL, GeoShape geography NULL) GO INSERT into CoolShapes (Name, GeoShape) values ( ISS Orbital Path,@ISSOrbit) I like this shape so much I m going to keep a copy of it
World Geography Global Datasets From ESRI Shapefiles
Load Global Maps
Load Global Maps select @ISSOrbit union all select GeoMap from dbo.world With a UNION, we simply plot the orbit on the Global ESRI Shapefile Map http://www.vdstech.com/world-data.aspx
GEOGRAPHY Case Studies INTERSECTION BUFFERS
Spatial Methods Type Example Syntax Buffer @IISOrbit.STBuffer(75000).STBuffer(radius) Intersect @IISOrbit.STIntersection(@China).STIntersection(object) Distance @China.STDistance(@Guatemala).STDistance(object) Crosses @IISOrbit.Crosses(@China).STCrosses(object) Within Contains @SQLDeveloper.STWithin(@SanJac intocollege.stbuffer(4000)) @SanJacintoCollege.STContains( @Jared).STWithin(object).STContains(object) www.nga.mil
STIntersection Method SELECT @ISSOrbit UNION ALL SELECT GeoMap FROM World WHERE Name='China' A human knows that the orbit crosses China, but how do we tell the computers? http://www.vdstech.com/world-data.aspx
STIntersection Method SELECT @ISSOrbit.STIntersects(@China) We know it intersects but WHERE? http://www.vdstech.com/world-data.aspx
STIntersection Method SELECT @ISSOrbit.STDifference(@China).STIntersection(@China) Can you see them? http://www.vdstech.com/world-data.aspx
STIntersection Method SELECT @ISSOrbit.STDifference(@China).STIntersection(@China).STBuffer(75000) UNION ALL SELECT @China Let s add a few.stbuffer(s) http://www.vdstech.com/world-data.aspx
MAKING IT LOCAL San Jacinto College
Make Some Developers insert into SQLDevelopers (Name, Latitude, Longitude, Altitude) values ('Jared Nielsen Dark Matter', 29.5786422, -95.2049992, 15) insert into SQLDevelopers (Name, Latitude, Longitude, Altitude) values ('Jared Nielsen', 29.5786422, -95.2049992, 15) insert into SQLDevelopers (Name, Latitude, Longitude, Altitude) values ('Nancy Hidy Wilson', 29.578, -95.2049, 14) insert into SQLDevelopers (Name, Latitude, Longitude, Altitude) values ('Robert Gremillion', 29.5552929,-95.1133171,16) UPDATE SQLDevelopers SET GeoPosition = geography::point([latitude], [Longitude], 4326) GO http://www.vdstech.com/world-data.aspx
San Jacinto College is Cool ALTER TABLE CoolShapes ADD GeoPosition geography NULL GO INSERT INTO CoolShapes (Name, GeoPosition) VALUES ('San Jacinto College', geography::point(29.5786422, -95.2049992, 4326)) http://www.vdstech.com/world-data.aspx
STIntersection Method SELECT GeoPosition.STBuffer(100) FROM CoolShapes WHERE Name='San Jacinto College' UNION ALL SELECT GeoPosition.STBuffer(30) FROM SQLDevelopers One Developer is Not Attending http://www.vdstech.com/world-data.aspx
STIntersection Method SELECT GeoPosition.STBuffer(100) FROM CoolShapes WHERE Name='San Jacinto College' UNION ALL SELECT GeoPosition.STBuffer(30) FROM SQLDevelopers WHERE NAME NOT IN ('Robert Gremillion') Who else is here? http://www.vdstech.com/world-data.aspx
More Methods DECLARE @Jared geography DECLARE @Robert geography DECLARE @Nancy geography DECLARE @SanJAC Geography DECLARE @JaredGhost geography SELECT @Jared = GeoPosition.STBuffer(5) FROM SQLDevelopers WHERE Name = 'Jared Nielsen' SELECT @Robert = Geoposition.STBuffer(5) from SQLDevelopers WHERE Name='Robert Gremillion' SELECT @Nancy = Geoposition.STBuffer(5) from SQLDevelopers where Name LIKE 'Nancy%' SELECT @SanJAC = Geoposition.STBuffer(100) from CoolShapes WHERE Name = 'San Jacinto College' SELECT @JaredGhost = Geoposition.STBuffer(2) from SQLDevelopers WHERE Name = 'Jared Nielsen Dark Matter http://www.vdstech.com/world-data.aspx
More Methods SELECT @Jared.STWithin(@SanJAC) = Boolean True SELECT @SanJAC.STContains(@Robert) = Boolean False SELECT @Jared.STDistance(@Nancy) = 61.832 meters Declare @BodyOdorPerimeter geography SELECT @BodyOdorPerimeter = @Jared.STBuffer(10) Declare @OlfactoryPerimeter geography SELECT @OlfactoryPerimeter= @Nancy.STBuffer(60) Do I stink? http://www.vdstech.com/world-data.aspx
More Methods SELECT @OlfactoryPerimeter.STOverlaps (@BodyOdorPerimeter) Boolean = 1 http://www.vdstech.com/world-data.aspx
JARED NIELSEN Serial Entrepreneur Investor Software Architect Questions?