· Geometry: Stores spatial data on a flat surface
· Geography: Stores spatial data on a sphere, or to be more exact the earth
Data can be inserted into a geography column in a table using
references to spatial data objects such as POINT, LINESTRING, POLYGON etc. Some
example inserts into a table that has a Location column of type geography are:
INSERT INTO Site (ID, Location) VALUES (1, 'POINT(51.508 -0.128)')--London
INSERT INTO Site (ID, Location)
VALUES (2, 'POINT(48.857 2.352)') --Paris
INSERT INTO Site (ID, Location)
VALUES (2, 'LINESTRING(1 1,2 3,4 8, -6 3)')
The spatial data types also
have built in methods allowing spatial computations to be carried out as part
of an SQL query. There are many such methods including: STDistance(), STIntersection(),
STUnion() and STDifference(). The first of these STDistance() calculates the
distance between two points or shapes, in metres when using the default
coordinate system, as shown in the example below:
DECLARE @p1 geography
SELECT @p1 = Location FROM Site WHERE ID = 1DECLARE @p1 geography
SELECT Location.STDistance(@p1) FROM Site WHERE ID = 2
The answer is just over 402793 metres which when divided by 1609.344
gives 250 miles which is correct given that the first point is in London and
the second one is in Paris.
So spatial shapes can be stored in a database and calculations
can be carried out on them in SQL queries. But how do we visualise spatial data?
Well one way is to the use the mapping facility in SQL Server Reporting
Services (SSRS).
Conveniently the AdventureWorks sample database has a
geography column called SpatialLocation in the Address table. So to demonstrate
the combined capabilities of SQL spatial data types and maps; I have devised an
example report in SSRS that allows a user to select an address in New York
together with a distance in miles and then display on a map all the addresses
that are within the distance.
I first wrote a query to return all the addresses in New
York. This query is used to populate the dropdown list for the user to select a
starting address:SELECT A.[AddressID], A.[AddressLine1] + ' '
+ ISNULL(A.[AddressLine2], '')
+ ' ' + A.[City]
+ ' ' + SP.StateProvinceCode
+ A.[PostalCode] AS [Address]
FROM [AdventureWorks].[Person].[Address] AS A
INNER JOIN [AdventureWorks].[Person].[StateProvince] AS SP
ON A.StateProvinceID = SP.StateProvinceID
WHERE SP.CountryRegionCode = 'US'
AND SP.StateProvinceCode = 'NY'
ORDER BY A.[PostalCode]
I then wrote a query to
return all the addresses within @Distance of the selected property. Note the
used of the STDistance() spatial method to calculate the distance between the
addresses. This query will be used to plot the addresses on the map:
DECLARE @Distance int = 100 -- ParameterDECLARE @NYAddress int = 770 – Parameter
SELECT A.[AddressID], A.[AddressLine1] + ' '
+ A.[City]
+ ' ' + SP.StateProvinceCode +
A.[PostalCode] AS [Address],
CONVERT(int, A.[SpatialLocation].STDistance(
A2.[SpatialLocation])/1609.344)
AS [Distance], A.[SpatialLocation]
FROM [AdventureWorks].[Person].[Address] AS A
INNER JOIN [AdventureWorks].[Person].[StateProvince] AS SP
ON A.StateProvinceID = SP.StateProvinceID
INNER JOIN [AdventureWorks].[Person].[Address] AS A2
ON CONVERT(int, A.[SpatialLocation].STDistance(A2.[SpatialLocation])/1609.344)
< @Distance
WHERE A2.AddressID = @NYAddress
ORDER BY [Distance]
Next step was to create a new blank SSRS report in SQL Server Data Tools and
add:
·
A SQL Server data source connecting to
AdventureWorks· Two data sets one for each of the SQL queries shown above
· Two parameters, one for each of the parameters used in the second query
· I dragged a Table item from the toolbox onto the report surface and configured it to display the Address and Distance columns for each for the selected addresses
· I then dragged a Map item from the toolbox onto the report surface and configured it to plot the position of each of the selected addresses on a Bing map. To do this I went through wizard screens as shown below:
On this screen I selected “Layer Type” as Point and I
checked the “Add a Bing Maps layer” option. I ignored the message about the
@Display variable because I have defined it as a parameter and so I knew it would
be OK.
I
then opened the Point Properties dialog for the Point Layer on the map and
changed the fill colour to Red to make it easier to see the points on the map.
The
result is below with 8 matching addresses shown for the 50 mile radius. Change
the New York Address and the distance and click View Report and the map is rescaled
and redrawn as required.
This is a simple example, but it shows how easy it is to
create a spatially aware application using SQL Server. The database engine
stores the locations and calculates the distances, while SSRS renders them
nicely as a familiar and easy to use map.
No comments:
Post a Comment