Working with SQL Server Spatial - Lessons1
Working with SQL Server Spatial - Lessons1
CONTENTS
Contents ..................................................................................................................................... 4
Database Creation................................................................................................................. 6
SQL Server Coordinate Systems ............................................................................................. 6
DDL Operations ..................................................................................................................... 8
Using WKT and WKB Conversion Methods for DML operations ............................................. 9
Converting geometries back to WKT.................................................................................... 12
Page 4
Working with SQL Server Spatial
Lessons
WORKSHOP PREPARATION
Normally, this workshop is taught using a VMware virtual system configured with Windows 7/8 and SQL
Server Express 2012 or 2014. If you have SQL Server loaded on your own desktop or laptop, you can
also use that. You can run most of the workshop on SQL Server 2008 R2 but you should really move to
at least the 2012 version.
SQL Server Express Edition is a free, easy-to-use, lightweight, and embeddable version of SQL Server
Standard Edition. It is free to download, free to redistribute, free to embed, and easy to use. It has all
the spatial capabilities found in the Standard Edition of SQL Server making it the perfect tool for learning
how SQL Server spatial works. You can get a copy of SQL Server Express from the following:
http://www.microsoft.com/en-us/server-cloud/products/sql-server-editions/sql-server-express.aspx
If you are using the provided VM, the material used in this workshop is located in the following
directory: C:\SQLWorkshop. Otherwise, the material is located wherever you may have copied it.
To prepare for your workshop, you need to make sure you have access to the workshop material as
well as access to your SQL Server database instance via the Management Studio. If you have any
questions here, please contact the instructor.
Page 5
Working with SQL Server Spatial
Lessons
Goals
Database Creation
The first step is to create some databases to use in this workshop:
1. Open the SQL Server Management Studio from the Start menu (or from the task bar).
2. Connect to your local SQL Server database instance.
3. Right click on Databases and create a new database called SpatialUser. We will use this one to run
some basic spatial tests.
4. Right click on Database and create a new database call Denmark. Later in this Lesson, we will load
some data into this database to further demonstrate spatial analysis queries.
5. Select New Query to open a SQL Query Window.
6. Make sure your database is set to SpatialUser, the default will be master:
Page 6
Working with SQL Server Spatial
Lessons
same SRID can be used when performing spatial operations. SQL Server uses the spatial reference
systems defined by the European Petroleum Survey Group (EPSG) standard.
1. To get a list of avaiLessonle coordinate systems and their reference id (SRID) execute the following
query:
This list is specific to geographic reference systems. For geographic data, an SRID is required and
must be in this list. For projected systems, the default SRID is 0.
2. While EPSG includes spatial reference identifiers for projected data, they are not included in the
definitions used by SQL Server. For example, Denmark uses EPSG25832:
in this case, no record is found. That's because this is a projected coordinate system and SQL Server
only contains SRID's for geographic coordinate systems.
3. If you are interested in the well-known text (WKT) definition for a specific coordinate system (like
WGS84) use the following query:
SELECT well_known_text
FROM sys.spatial_reference_systems
WHERE authority_name = 'EPSG'
AND authorized_spatial_reference_id = 4326;
The results should be:
SELECT unit_of_measure
FROM sys.spatial_reference_systems
WHERE authority_name = 'EPSG'
AND authorized_spatial_reference_id = 4326;
The answer should be meters.
Page 7
Working with SQL Server Spatial
Lessons
The answer should be 391. Oracle also uses SRIDs but they have a mix of their own as well as EPSG.
In Oracle the count is 4478 but they also include projected as well as geographic SRID's. Oracle
allows for database level coordinate system transformation which is why they have a larger number
of SRID's avaiLessonle.
DDL Operations
Creating a new table or adding geometry/geography to an existing table is a straight forward operation.
2. You can enforce a specific SRID via a constraint and if you are using geography, this is a good idea
and is a best practice:
4. To verify your new table, refresh your SpatialUser database and then expand the table
dbo.INGRCustomers, then expand both columns and constraints.
5. Creating a table that uses geometry is a similar process:
CREATE TABLE [dbo].[LocalPubs] (Name nvarchar(255), District varchar(32),
Location geometry);
Page 8
Working with SQL Server Spatial
Lessons
Conversion from WKT uses the static method STGeomFromText or one of its sub-methods. Since binary
is difficult to enter; only one example is given for WKB conversion which uses STGeomFromWKB or one
of its similar sub methods. The general format is:
geometry::STGeomFromText('geometry_tagged_text',SRID)
geography::STGeomFromText('geometry_tagged_text',SRID)
To make things simpler, many of these examples will use TSQL and a pseudo table rather than a real
table. Whether or not a real table is involved does not matter, the steps are the same.
1. Here is how to insert a simple geography point using WKT and STGeomFromText:
INSERT INTO INGRCustomers VALUES ('Chuck','Woodbury','USA',
geography::STGeomFromText('POINT(55 9)', 4326));
2. Here is the same operation using the STPointFromText sub method that validates the input string to
that ensure only a point is inserted:
INSERT INTO INGRCustomers VALUES('Chuck','Woodbury','USA',
geography::STPointFromText('POINT(56 10)', 4326));
3. You could also do the same thing just using the Point sub method (this only supports 2D). This is a
special method mainly used for loading GPS points:
INSERT INTO INGRCustomers VALUES ('Chuck','Woodbury','USA',
geography::Point(55,10,4326));
This is due to the constraint you applied earlier. Should you mix types within a table? You can do it
but personally I do not think it is a good practice.
5. You also have a constraint on the SRID. Try the following:
Page 9
Working with SQL Server Spatial
Lessons
If you are using geodetic data, you should use SRID constraints as a precaution against inserting a
record with a coordinate system different from what is already stored in the table.
6. Updates are a similar process but you have to update the entire geometry, you cannot change just
one of the coordinates. The exception is the SRID, this can get updated without affecting the actual
stored geometry value. Here is an update example:
7. Here is a different example, in this table, GeomCol1 is the only column you have to populate since id
is identity and GeomCol2 is a function based derived column:
CREATE TABLE SpatialTable (id int IDENTITY PRIMARY KEY,
GeomCol1 geometry, GeomCol2 AS GeomCol1.STAsText() );
9. The purpose of GeomCol2 is just to show you the text representation of the actual geometry stored
in GeomCol1. To see the contents, execute :
10. Look close and you will see a Spatial results tab in the
Management Studio. Any time spatial data is involved,
you can see the results graphically
Page 10
Working with SQL Server Spatial
Lessons
11. There are several methods you can use when inserting data. Here are some alternatives that
illustrate the various methods as well as showing you some basic TSQL methodology:
a. In this example, you are creating and selecting a polygon simultaneously in order to display it.
This is useful if you want to see what a provided set of data looks like:
SELECT geography::STPolyFromText(
'POLYGON(
( -77.053223 38.870863,
-77.054682 38.873043,
-77.057880 38.872800,
-77.058491 38.870219,
-77.055562 38.869067,
-77.053223 38.870863
),
(
-77.055820 38.870286,
-77.056936 38.870737,
-77.056732 38.871706,
-77.055476 38.871848,
-77.054919 38.870979,
-77.055820 38.870286
)
)',
4326
)
Could you have updated a record this way? Yes, here is the syntax:
c. This is an example of a multi-linestring. Notice how the different lines are in separate (…):
Page 11
Working with SQL Server Spatial
Lessons
e. Here is an example of a geometry collection; these contain more than one geometry type. This
uses the geometry collection method and a WKT definition:
f. The simplest way to load geometry based data is the Parse sub method, it assumes that the SRID
=0 and that the geometry is correctly defined (in this case, we are using 3D data):
12. Optional: You can also use WKB but it is more difficult if you are not used to use binary format.
However, programmatically, it can be easier, and is also how GeoMedia does it internally via the SQL
Server data server:
DECLARE @ByteOrder bit
DECLARE @GeometryType int
DECLARE @longitude float
DECLARE @latitude float
DECLARE @WKB varbinary(max)
DECLARE @Point geography
--
SET @ByteOrder = 0
SET @GeometryType = 1
SET @longitude = 21.01
SET @latitude = 52.23
--
SET @WKB = CAST(@ByteOrder AS binary(1)) + CAST(@GeometryType AS binary(4)) +
CAST(@longitude AS binary(8)) + CAST(@latitude AS binary(8))
SET @Point = geography::STPointFromWKB(@WKB, 4326)
SELECT @Point, @Point.AsTextZM()
stored format back to either WKT of WKB. The method you use will depend on what information you
want. The standard methods only convert to 2D WKT but there are extended methods for the retrieval
of 3D data as well. The 2 main methods are:
geometryCol.STAsText() – static method for conversion to 2D WKT
geometryCol.AsTextZM() – extended method for conversion to 3D WKT
1. STAsText() is the most common way to convert to WKT but it only supports 2D data:
SELECT id, GeomCol1.STAsText() FROM SpatialTable;
2. The last linestring inserted was 3D and notice, no z values are shown. To get the Z's you need to use
an extended method called AsTextZM():
SELECT id, GeomCol1.AsTextZM() FROM SpatialTable;
3. The extended methods above are the most commonly used but there are others, for example, if you
want to the WKB representation of the data, use STAsBinary():
Page 13
Working with SQL Server Spatial
Lessons
The methods above work for both geometry and geography types and are useful when you need to see
the content of a geometry column. There are other methods and extended methods available for
examining geometry data but we will save those for the next Lesson.
Page 14
Working with SQL Server Spatial
Lessons
Goals
1. Open Microsoft SQL Server Management Studio and connect to your local database instance.
2. Expand databases and right click on Denmark. Select Tasks>Restore>Database.
3. On the Restore Database dialog, select Device under Source and then select the … browse button.
4. Navigate to C:\SQLWorkshop\Data, select Denmark.bak, and then select OK on the Select Backup
Devices dialog.
5. Select the Files page on the Select a page list (on the left) and make sure the Restore As fields reflect
the location of the files for the current Denmark database.
6. Select the Options page on the Select a page list (on the left) and select the Overwrite the existing
database option.
7. Select OK to load the backup file. If everything work, you should see the following message:
8. Verify this by expanding the Denmark Database and then expanding Tables. The list should be
similar to that shown below:
Page 15
Working with SQL Server Spatial
Lessons
9. For one last check, right click on dbo.Denmark and select Select Top 1000 Rows. A query window
should appear. On the lower half, select the Spatial results tab. You should see the following:
This is a public domain dataset that we will use for many of the Lessons that follow. Most of the tables in
this dataset contain geometry columns using the EPSG25832 coordinate system. Those tables
containing WGS at the end of their names use geography columns with an SRID of 4326 (WGS84).
1. Checking the validity of the data is more important if you are doing manual inserts via WKT. GIS
applications verify topology and will not create bad data. But loading data via WKT can be prone to
problems. Here is a simple example of using .STIsValid() and .MakeValid():
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 1 1, 1 0, 1 1, 2 2)', 0);
SELECT @g.STIsValid() AS VALID, @g.ToString() AS WKT;
SET @g = @g.MakeValid();
SELECT @g.STIsValid()AS VALID, @g.ToString() AS WKT;
Note the change in the value for 0 to a very small number. This is one of the issues I have seen with
this method so be careful.
2. In SQL Server 2012, there is a command that gives you a better idea of the actual problem
encountered:
DECLARE @g geometry;
SET @g = geometry::STGeomFromText('LINESTRING(0 2, 1 1, 1 0, 1 1, 2 2)', 0);
SELECT @g.IsValidDetailed() AS DETAIL, @g.ToString() AS WKT;
b. Updating an incorrectly set SRID is also simple, here is an example for the same table:
Update CitiesWGS SET GEOM_POINT.STSrid = 4326;
Notice that STSrid does not use (), this is because it is a property of the geometry and not a
function that does something.
4. Sometimes it is useful to know the geometry type that is being stored.
Page 17
Working with SQL Server Spatial
Lessons
Notice in the second case, two different geometries were found. How would you determine
the count for each one?
b. Here is the answer to the question posed above:
SELECT COUNT(*) FROM EuropeWGS
WHERE Geometry.STGeometryType() = 'MultiPolygon';
Result: 28
5. Here are two examples of selecting components of a point geometry, one for geometry and one for
geography:
a. This query returns the X, Y, and Z values associated with a point:
SELECT Geometry.STX AS X, Geometry.STY AS Y, Geometry.Z as ELEV
FROM Airports;
6. For lines, you can retrieve the start point, end point, or any point in between.
a. The start and endpoints are pretty straight forward:
SELECT Geometry.STStartPoint() AS STARTPT, Geometry.STEndPoint() as ENDPT
FROM Railways;
b. But for points in between the start and endpoint, you need to know which point you are
after. For example, maybe you need the 4th point from the Railway who’s PID=1, and you
need the text representation of that. Here is how you do it:
SELECT Geometry.STPointN(4).STAsText() FROM Railways WHERE PID=1;
Result: POINT (608899.73423396423 6134213.9613970639)
Page 18
Working with SQL Server Spatial
Lessons
7. A similar method works for polygons, for example, how many polygons make up the country of
Demark:
SELECT Geometry.STNumGeometries( ) FROM EuropeWGS
WHERE Name='DENMARK';
b. For the area of polygons, just add .STArea() and you can also use .STLenght() to find the
perimeter. Here is an example using the query in step 7 to find the area of
the resulting polygon:
Select Geometry.STGeometryN(5).STArea() AS Area,
Geometry.STGeometryN(5).STLength() AS Perimeter,
FROM EuropeWGS WHERE Name='DENMARK'
There are several ways to create spatial indexes, you can use the create index syntax via sql or use the
create index interface in the SQL Server Management Studio. The key to having a performant spatial
index is determining an optimal bounding box for a table's data distribution. Currently, SQL Server has
no straight forward method for calculating the bounding box but later we will examine methods that will
help make this easier. For now, the goal is just to create spatial indexes to support spatial analysis
queries.
Page 19
Working with SQL Server Spatial
Lessons
1. To use SQL Server Management Studio to create indexes, first query on the table Denmark and
examine the results in the Spatial results view. We are using Denmark because all of our projected
data should be confined here:
SELECT Geometry FROM Denmark;
2. By examining the data distribution, it appears that all the data lies roughly within the bounding box
Xmin=441000, Ymin=6040000, Xmax=900000, Ymax= 6410000. For our projected data, this is the
bounding box we will use.
3. Expand the Airports table and right click on Indexes. Then select New Index…>Spatial Index from
the drop down menu.
a. On the General page, enter Airports_SIDX for the index name and then select the Add
column button and select the appropriate geometry column (Geometry).
b. On the Options page, just leave the defaults settings as is.
c. On the Storage page, set the Filegroup to Primary
d. On the Spatial page, enter the values from Step 2 into the bounding box and take the
defaults for everything else:
Page 20
Working with SQL Server Spatial
Lessons
e. Select the drop down menu for Script located just above the bounding box and select New
Query Edit Window. The SQL syntax for the index creation will show up in a new query
Window.
f. Select Ok on the Create new Index dialog and the index will be created.
g. The spatial index Airports_SIDX should appear under the index tab in the Object Explorer.
h. Now switch to the newly create query window and review the index syntax, it should be
similar to that shown below:
CREATE SPATIAL INDEX [Airports_SIDX] ON [dbo].[Airports]([Geometry])
USING GEOMETRY_GRID
WITH (BOUNDING_BOX =(441000, 6040000, 900000, 6410000),
GRIDS =(LEVEL_1 = MEDIUM,LEVEL_2 = MEDIUM,LEVEL_3 = MEDIUM,LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 16, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
GO
4. The reason for creating the syntax is so we can reuse it for the other tables. Change the index name
and the table name and execute the above query for each of the tables listed below:
indexname tablename
Denmark_SIDX Denmark
Railways_SIDX Railways
Roads_SIDX Roads
UrbanAreas_SIDX UrbanAreas
NaturalAreas_SIDX NaturalAreas
5. That was a lot of indexes but notice we left out the geography based columns, we will come back to
those later.
Spatial analysis involves a two pass filtering process; the first pass uses .Filter which is just an index tile
comparison, while the computationally intensive second pass refines the results. The less data in the
second pass, the faster the spatial query performs. This is why having an optimal index is key to spatial
query performance.
This section will demonstrate some basic spatial analysis methods that can be used with your data.
Page 21
Working with SQL Server Spatial
Lessons
1. Since it only compares index tiles, .Filter is the fastest comparison operator you can use. It is
considered a coarse filter and may return erroneous results, but it is useful as
a spatial filter to all the data in a specified area. For example, find all the
Urban Areas in Sjaelland:
SELECT a.Name, a.geometry from UrbanAreas a, Denmark b
WHERE b.Name = 'SJAELLAND'
AND a.geometry.Filter(b.geometry)=1
3. Since STWithin does not include the boundaries, we need to try a different operator here, this time
use STIntersects:
SELECT a.Name, a.geometry from UrbanAreas a, Denmark b
WHERE b.Name = 'SJAELLAND'
AND a.geometry.STIntersects(b.geometry)=1;
5. The only comparison operator that does not use true or false is
.STDistance, instead, it expects a distance value. For example, find all of
the urban areas with 10 km of Copenhagen. Since you cannot embed
6. Find all the Railways that cross UrbanAreas. You would use the
Page 22
Working with SQL Server Spatial
Lessons
7. Find all the NaturalAreas that overlap UrbanAreas. You would use the following
syntax here geometry1.STOverlaps(geometry2) and the result should similar to
that below
8. Find all the Roads within the island of LANGELAND (Denmark table). You would need to query on
the name first and then use either .STWithin. The answer is shown at right .
9. The named spatial operators (with the exception of STDistance) are all based on the STRelate
method. This method relies on the DE-9IM pattern matrix to do its calculations. Since the matrix
patterns are difficult to use, the named methods make it easier, but you can still use the matrix for
specialized queries. For example, here is the answer to step 8 using STRelate:
SELECT a.geometry from Roads a, Denmark b
WHERE b.name='LANGELAND'
and a.geometry.STRelate(a.geometry,'T*F**F***')=1;
10. How would you write the query used in Step 7 using STRelate instead of STOverlap?
11. When doing spatial analysis it is important to know that you can get duplicate results depending on
the type of query you are doing. For example, if you want to find all the polygons that contain a
specific road, you may get the same polygon for each segment of the same road contained by the
polygon. This is illustrated below:
Page 23
Working with SQL Server Spatial
Lessons
Spatial Functions
SQL Server also offers a variety of spatial functions that operate on and
return geometry results based on specific criteria. Most of the functions, like STBuffer, STBoundary, and
STCentroid operate on one input geometry, but there are also aggregation functions like STUnion and
STIntersection that combine results from two different geometries. In this section, you will examine
how to use some of these functions.
1. STBuffer allow you to create buffer zones around geometries. For example, if you need a 500m
noise buffer around your railways, you could make the following query:
SELECT geometry.STBuffer(500) FROM Railways;
2. STCentroid and STPointOnSurface are similar functions for polygons but a centroid
may not necessarily be in the polygon while a point on the surface is guaranteed to
be on or in the polygon. In this example, we will combine the results:
SELECT Name, Geometry, Geometry.STCentroid() as Centroid,
Geometry.STPointOnSurface() as PtOnSurf
FROM Denmark;
To toggle between the geometries used in spatial results, use the Select Spatial Column list on the
right of the display.
3. STUnion can be used to combine results from different geometries but you need to be careful with
STUnion as it can produce a lot of results. Here is an example of combining FYN with LANGELAND:
WITH
FYN as (SELECT Geometry from Denmark where name='FYN'),
LGL as (SELECT Geometry from Denmark where name='LANGELAND')
SELECT a.geometry.STUnion(b.geometry) from FYN a, LGL b;
This uses the with syntax which allows you to create pseudo tables on the fly.
Page 24
Working with SQL Server Spatial
Lessons
5. STEnvelope returns simple polys containing the original geometry of the data:
SELECT geometry.STEnvelope() from Denmark;
Looking close at STEnvelope, can you see a way to calculate an optimal bounding box to use with
spatial indexes? With SQL Server 2012, there is an even better way!
6. You can also string together functions where appropriate:
SELECT geometry.STBoundary().STEnvelope() from Denmark;
SELECT geometry.STEnvelope().STBoundary() from Denmark;
7. Reduce can be used to thin the points used in lines and polygons. It uses the Douglas-Peucker
algorithm with the provided tolerance. For example:
SELECT geometry.Reduce(5000) as reduced from Denmark;
1. UnionAggregate() combines multiple spatial objects into a single object. Here is an example using
Denmark:
2. If you combine UnionAggregate with STEnvelope, you get an optimal bounding box
for use with a spatial index:
3. If you want to extract the coordinates for use as a bounding box, use the following:
SELECT geometry::UnionAggregate(Geometry).STEnvelope().STStartPoint().STAsText(),
geometry::UnionAggregate(Geometry).STEnvelope().STPointN(3).STAsText()
FROM Denmark;
Page 25
Working with SQL Server Spatial
Lessons
4. You could have done the same thing using EnvelopeAggregate, which bypasses the need to
STEnvelope in Step3 (in this case, we are using Roads):
SELECT geometry::EnvelopeAggregate(Geometry).STStartPoint().STAsText(),
geometry::EnvelopeAggregate(Geometry).STPointN(3).STAsText()
FROM Roads;
6. ConvexHullAggregation creates a convex hull polygon that encloses the complete the spatial objects
in the query. This is most commonly used for points and lines but can be used with polygons as
well. Here is an example using Airports shown as a union all with the original data:
SELECT geometry::ConvexHullAggregate(geometry) FROM Airports
UNION ALL
SELECT geometry from Airports;
Page 26
Working with SQL Server Spatial
Lessons
Creating a GeoMedia database in SQL Server is just a matter of creating an empty SQL Server database
and then creating GeoMedia's required metadata tables. Once the metadata has been created, there
are specific defaults you need to assign that will make working with spatial tables a lot easier.
The goal of this Lesson is to step you through the basic process of configuring a database for creating
and loading tables via GeoMedia and then demonstrating how GeoMedia uses the database.
Goals
1. In SQL Server Management Studio, right click on Database and select New Database.
2. Create a database named GeoMedia and select OK.
3. There are a couple of ways to create metadata but I generally recommend using Database Utilities,
particularly for non-production databases. In production databases, the entire process is generally
scripted and metadata should be part of that. Select Database Utilities from the GeoMedia
Professional/Utilities folder under the Start menu.
4. Set the Database type to SQL Server Spatial, then enter you server name (your system name). You
should be able to use Windows authentication because you are the admin on the system. Select
the GeoMedia database from the database list. You should see the Database Utilities dialog
appear:
Page 27
Working with SQL Server Spatial
Lessons
5. Database Utilities must be run by a user in the database role DBO for table to be properly created.
To create metadata tables, select the Create Metadata Tables button. You will get the following
message if the process is successful:
Processing of Create Metadata Tables is completed.
GeoMedia metadata system is modified.
Select OK to continue.
6. If you already know the GeoMedia coordinate system you need to use as the default with this
schema, you can set it via the Assign Coordinate System button. You can set this parameter at any
time but we will go ahead and set it now:
a. Select the Assign Coordinate System button on Database Utilities.
b. On the Coordinate Systems dialog, select the New button.
c. On the Coordinate System Properties dialog, select the Load button.
d. Navigate to C:\SQLWorkshop\Data then select Alabama.csf and then select OK.
e. Back on the Coordinate System dialog, select the Set As Default button. (Default) should
appear next to the listed coordinate system:
7. Leave Database Utilities running and switch back to the SQL Server Management Studio.
8. Right click on the GeoMedia database and select Refresh. Now, if you expand tables you should see
the metadata tables:
Page 28
Working with SQL Server Spatial
Lessons
1. To see the default contents of GParameters, right click on the table and select Edit Top 200 Rows.
These are the defaults used when the metadata is created:
2. In order to set up GParameters, you need to know a few things about your data:
a. DefaultCoordinateSystem: What is the default GeoMedia coordinate system you want to
use? For projected data, this can be anything, but for geographic; this coordinate system
must exactly match the parameters used for the selected SRID. This parameter was added
Page 29
Working with SQL Server Spatial
Lessons
when you assigned a default coordinate system to use via Database Utilities. The GVALUE
for this parameter corresponds to the CSGUID for the coordinate system stored in the
GCoordSystem table.
b. TypeForNativeGeometryStorage: Are you using geographic or projected data? This
determines the default data type for storing geometries as well as the SRID. The default
setting is geometry (projected data).
c. DefaultNativeGeometrySrid: For geographic data, you need to set the default SRID to use.
The default setting is 0 for projected data, but for geographic, you need to select an SRID
that already exists in SQL Server. If you pick wrong, you can corrupt your data so be careful
here.
d. Upper and lower bounds: What is the range of your data? This is the default bounding box
used when GeoMedia creates spatial indexes for your data and is only required for
projected geometries. The default range is typically two big to create an optimal index. If
you are unsure of a range to use, you can always change this later and re-index. For now,
set the following values:
XLowerBound=350000 YLowerBound=3339000
XUpperBound=725000 YUpperBound=3880000
Make sure you tab out of the field in order to commit the data. The final results should
reflect:
3. There are some other key tables in the metadata structure that you should be aware of. Right click
on GAliasTable and select Select Top 1000 Rows:
Page 30
Working with SQL Server Spatial
Lessons
This table is the controller table for the metadata. It was added so administrators could have
control over the metadata table names. The TableType cannot be changed but you can change
values in the TableName column as long as a table or view with that name exists and the column
structure exists. I never quite understood development's reasoning here, but it was added for
flexibility.
4. GFeatures governs what tables or views are visible inside of GeoMedia. If a table or view is not
listed here, a GeoMedia will not be able to see it even if there is other metadata related to that
table/view. Administrators can temporarily remove feature classes from use using this table.
5. GFieldMapping controls data type overrides as well as the relationship between GeoMedia's GDO
geometry column and the native spatial geometry column. It also stress the NATIVE SRID used by
the native geometry. This allows you to override defaults set by GParamaters and is useful for
tables created outside of GeoMedia. Right click on GFieldMapping and select Design:
6. GindexColumns is used for views, and if you want views to function correctly in GeoMedia, the view
will need information in this table. Right click on GindexColumns and select Design:
Page 31
Working with SQL Server Spatial
Lessons
GeoMedia does not care where a feature class is a table or a view; it just needs to know how to
access the data. Since a view does not have a key column, this table lets you assign a pseudo key
column that GeoMedia can use to access the data. Any column will do as long as it can act as a key
(unique and not null).
7. In the Object Explorer, expand Views. Notice the view ModifiedTables, this view provides the
object id for tables and views (from SQL Server) in the current schema and is used when tracking
DML activity via GeoMedia's ModificationLog table. Right click on this view and select Select Top
1000 Rows:
As you can see, it is already providing information about the metadata tables we created in this
schema. Data changes are tracked via the ModifiedTableID column and the key field value for the
row that changed. GeoMedia allows tables to have up to 7 columns that define the primary key.
Inserts, updates, and deletes made via GeoMedia are tracked in the ModificationLog table and
identified by the ModifiedTableID.
8. In the Object Explorer, expand Programmability>Functions>Scalar-valued Functions. The 4 scalar
functions you see are also part of GeoMedia's metadata. As you add users to your database, you
must ensure they have execute privileges on these 4 functions. The functions control the flow of
information to and from GeoMedia by converting the geography/geometry data type (not data!) to
and from binary format.
9. When accessing a geometry data type, GeoMedia uses SqlGeometry2Binary. Here is what the
function looks like:
Page 32
Working with SQL Server Spatial
Lessons
So all this function does is convert a geometry data type to a varbinary(max) data type. The data is
unchanged. A similar function works with the geography data type.
10. It’s the same when writing geometry data, GeoMedia uses the Binary2SqlGeometry function to
convert its varbinary(max) data type containing the geometry data type. Check it out on your own if
you are interested.
When creating tables in a SQL Server native spatial warehouse, FCD uses the default settings in the
GParameters table to determine the spatial data type, SRID and bounding box to use for spatial indexes.
1. Open GeoMedia Professional from the Start menu or the shortcut on your task bar.
2. When prompted, create a new workspace.
3. Create a new connection using Warehouse>New connection
a. Set the Connection type: to SQL
Server Spatial Read-Write
b. Set the Connection name: to
GeoMedia Native Spatial
c. Set the Server: to your local SQL
Server system (SQLWorkshop)
d. Use Windows Authentication
e. Set the Database: to GeoMedia
f. Select OK to establish your
connection.
4. Save the Workspace so we can use it later if need be. Select File>Save Workspace and enter
GeoMediaData.gws for the workspace file name. Select Save and now you have a saved workspace.
5. Verify the workspace coordinate system by selecting View>GeoWorkspace Coordinate System.
Notice that the workspace coordinate system is the same one we setup as the default coordinate
system in the last Lesson. When establishing a new first connection, GeoMedia will automatically
set the workspace coordinate system to match the default warehouse coordinate system. If no
default was present, GeoMedia would use the first coordinate system it found in the GCoordSystem
Page 33
Working with SQL Server Spatial
Lessons
table. This is why setting a default coordinate system is so important. After verifying the coordinate
system, select Cancel on the GeoWorkspace Coordinate System dialog.
6. Create a new connection (Warehouse>New connection), select Access as the Connection Type,
change the Connection name to AlabamaSampleData, and then select Browse. Navigate to
C:\SQLWorkshop\data and select AlabamaProj.mdb. This will give us an area in which to work in.
7. Select Legend>Add Legend Entries, expand the + next to AlabamaSampleData and then check the
box next to State. Select OK and you will display my home state of Alabama.
This will give us an area to work in when we create new feature classes and digitize some data.
8. Select Warehouse>Feature Class Definition to access the Feature Class Definition dialog.
9. Select the GeoMedia Native Spatial connection from the list of Feature Classes and then select New
to create a new feature class.
10. Create an oriented point feature class by doing the following:
a. On the General tab, enter PointFeatures in the Name field.
b. Verify that the Geometry Type is Point and the coordinate system is set to the default. You
can optionally enter a description for this table if you want.
c. Select the Attributes tab
d. Set the primary key column first, select the first field in the list and then select the Set
Primary Key button. A key symbol should appear in the Key column.
e. Change Attribute1 in the Name column to PointID and then set the Type to Autonumber.
This ensures that the key column uses an identity and is automatically populated as new
records are added.
f. Add another column called CreateDate and set the type to Date.
g. Add another column called PointName and set the type to Text with a Length of 15.
h. When complete, the New – PointFeatures dialog should be similar to the one shown below:
Page 34
Working with SQL Server Spatial
Lessons
15. From this same dialog, you can review the definition of feature classes, edit the feature class
definition, and even copy the feature class. Editing the definition of a feature is limited and in many
Page 35
Working with SQL Server Spatial
Lessons
cases, may be prevented by specific database options and privileges. For production databases, the
best practice is to manage feature class definitions via the SQL Server Management Studio.
16. Select Close on the Feature Class Definition dialog.
1. To insert a new oriented point, select the Insert Feature button from the toolbar. The Feature
editing toolbar will appear.
a. From the drop down list on the left, expand the GeoMedia Native Spatial connection and
select PointFeatures.
b. Use the option Place at angle and set the angle to 45 degrees:
Page 36
Working with SQL Server Spatial
Lessons
6. Switch to the SQL Server Management Studio (but do not exit GeoMedia).
7. Right click on the GeoMedia database and select New Query. In the query window, execute the
following query:
select * from PointFeatures;
You have two geometry columns. The native spatial data is stored in Geometry_SPA and the GDO
geometry is stored in the Geometry column. SQL Server does not store the point orientation so
GeoMedia uses the secondary geometry to store that information. To see the values that are
stored, execute (note that GeoMedia always stores 3D):
select Geometry_SPA.AsTextZM() from PointFeatures;
8. In the Management Studio Object explorer, expand the dbo.PointFeatures table and then expand
triggers. You should see two triggers, PointFeatures_Geometry_SPA_ins and
PointFeatures_Geometry_SPA_upd. These are maintenance triggers used to monitor insert and
update operations on this feature class. The trigger detects if only the native geometry field is
inserted or updated in which case, it inserts a null to the GDO geometry. This ensures that the GDO
field, which can only be modified from within GeoMedia, is NULL when an edit occurs outside
GeoMedia.
9. Here is an example of the update trigger in action, execute the following:
Update PointFeatures set Geometry_SPA =
geometry::STGeomFromText('POINT(503000 3828900)',0) where PointID =1;
Page 37
Working with SQL Server Spatial
Lessons
Notice GeoMedia's GDO geometry column is now NULL. What is the consequence of this action?
a. Switch back to GeoMedia and select Warehouse>Connections
b. Select the GeoMedia Native Spatial connection from the list and then select the Reopen
Connection button (this will refresh the map window with your change).
c. The geometry has been moved but if you select the point then select Geometry Information
you will notice that the point orientation has been lost, it is now just a simple point.
Notice that no GM_GEOM is needed for the simple LINESTRING. It's only the linestring that
includes the arc that is stored in both locations. The GDO geometry (GM_GEOM) stored the
actual 3 point arc while the Native_Geom field stores the stroked representation of the arc.
b. In the SQL Server Management Studio, execute the following:
SELECT AreaID, AreaName, Geometry as GM_GEOM,
Geometry_SPA.AsTextZM() as Native_Geom
FROM AreaFeatures;
Page 38
Working with SQL Server Spatial
Lessons
Just like the previous example, GM_GEOM is not needed for the simple polygon. It's only
the circle polygon (containing 2 arcs) that is stored in both locations. Again, the
Native_Geom field stores the stroked representation of the arc.
If you edit this data outside of GeoMedia, the GM_GEOM column will be set to NULL and
you will lose the original ARC definition and only retain the stroked version.
11. Text Features are handled a little differently. The only geometry stored is the point location, the
rest of the text and its formatting information is embedded in the GM_GEOM. Execute the
following:
SELECT TextID, StoredText, Geometry as GM_GEOM,
Geometry_SPA.AsTextZM() as Native_Geom
FROM TextFeatures;
Export/Import Operations
The Export to SQL Server command is the best tool to use to bulk export data from an alternate data
store to a SQL Server 2008 R2 or later database for use with the GeoMedia product suite. The command
is intended for bulk loading large amounts of data into a database by generating ASCII files that can be
used by SQL Server’s own Bulk Loader application (bcp). This command is not intended to be used as an
update tool. If you are planning to migrate existing SQL Server data to SQL Server spatial, this is
probably the best tool to use.
The export process takes the source data as is with no modification. Source data that is not from
another database may have problems once it is imported into the SQL Server spatial environment.
Column names may be illegal, primary key columns may not exist, and there may be data issues. After
import, verify that the data model conforms to the requirements of SQL Server spatial, and make any
necessary corrections before using the data in the GeoMedia environment. You should also make sure
that spatial indexes are created on the spatial geometry columns after any import operation.
Page 39
Working with SQL Server Spatial
Lessons
3. On the Export to SQL Server dialog, expand AlabamaSampleData and select State, Counties, and
Roads_Primary from the list.
4. In the Export options section, select Export native spatial format and verify that the SRID id set to
Projected (SRID 0).
5. Set the Export folder to C:\Temp and then select the Apply button.
6. You will see the message dialog Export Complete appears when the process is complete. Select OK
on this dialog and then select Close on the Export to SQL Server dialog.
7. Switch to Window's File Explorer and navigate to C:\Temp.
8. Open the Export.log file. This shows you the results of the export job, the time it took to export
each feature class, and the number of features exported. If an error occurred during the process,
the error would show up here.
9. Open Alabamasampledata_state_pre.sql in a text editor like Notepad and examine the contents:
SET ANSI_PADDING ON
CREATE TABLE State(
fips_state NVARCHAR(2) NULL,
ID INT IDENTITY(1,1),
Geometry VARBINARY(MAX) NULL,
Geometry_SPA GEOMETRY NULL,
PRIMARY KEY(ID))
GO
The purpose of the *_pre.sql file is to create the table used to store the data. Close notepad and
proceed.
10. Open Alabamasampledata_state.dat in a text editor like Notepad and examine the contents. This
table stores the data what will be bulk loaded into the table created by the *_pre.sql file.
11. Open Alabamasampledata_state_post.sql in a text editor like Notepad and examine the contents.
This file populates the metadata tables used by GeoMedia. It also creates the maintenance triggers
used by the table.
12. The file that controls the import operation is import.bat. This command need to be run in an
Administrative Command Window and can only be run on a system that has the SQL Server
Management Studio installed.
a. Open a command window from the Start menu by right clicking on Command Prompt and
selecting Run as Adminstrator.
b. Navigate to C:\temp: cd C:\Temp
c. Enter import.bat to get the syntax of the command, you have two choices:
import server_name db_name admin_user admin_pswd Y
import server_name db_name admin_user admin_pswd
You should always create metadata table via Database Utilities so avoid using the Y option.
Instead, enter:
You can use "" "" here because you are the administrator on this system. Otherwise, you
would use a user/password that had dbo privileges on the database. The import process is
very fast and should complete in just a few seconds.
Page 40
Working with SQL Server Spatial
Lessons
13. Switch to SQL Server management Studio, go to the Object Explorer, right click on the GeoMedia
database and select Refresh.
14. Expand Tables and verify that Counties, State, and Roads_Primary are now in the list.
15. Switch to GeoMedia and select Warehouse>Connections. On the Connections dialog, select the
GeoMedia Native Spatial connection and then select the Reopen Connection button.
16. On the Legend, right click on PointFeatures and select Delete then answer Yes when prompted.
Repeat the process for TextFeatures, AreaFeatures, LinearFeatures, and State.
17. Select Legend>Add Legend Entries. On the Add Legend Entries dialog, select the checkbox next to
the GeoMedia Native Spatial connection to highlight all the feature classes in this connection. Select
OK to display the results:
Page 41
Working with SQL Server Spatial
Lessons
4. Switch to the Advanced tab. From here you can control the output process. The default Output
setting are correct here, just review them.
Since you are coming from an existing database, the key information is correct. If you are coming
from a non-database source, you will need to make sure you are creating a new key column. Always
double check the target coordinate system. In this case, it should be using the default coordinate
system set in the target.
5. Select the row containing Antennas and then select the Select Source Attributes button. This lists
the columns in the source table and
allows you to turn off columns you do
not want to transfer. This is a capability
missing from the Export to SQL Server
process. Select Cancel on this dialog.
6. Select OK to output the features, you
will be prompted whether to continue,
just select Yes.
7. When the process is finished, you will
get a confirmation dialog, just select OK.
The new feature classes should show up
on the legend. You will notice that this
process is a lot slower than the Export to
SQL Server process but it is also a lot
more flexible.
8. Save your workspace and exit from
GeoMedia.
Page 42
Working with SQL Server Spatial
Lessons
Optimizing Indexes
The default spatial indexes created by GeoMedia use the bounding box set in the GParameters table and
just create a basic spatial index. In some cases, this may be sufficient but for tables containing a large
amount of data, the spatial index will not be optimal. Also, keep in mind that the Export to SQL Server
process DOES NOT create spatial indexes and you will need to do that manually if you want performance
from spatial filters (in GeoMedia) and spatial analysis queries (outside of GeoMedia). It is the
responsibility of the DBA to create and maintain optimal spatial indexes.
In the previous sections, we used Export to SQL Server to migrate State, Counties, and Roads_Primary to
the GeoMedia database so none of these have spatial indexes. We will need to fix that lapse in this
section.
1. In SQL Server 2012, you can use one of the new aggregation commands to determine an optimal
bounding box for the spatial index:
SELECT
ROUND(geometry::UnionAggregate(Geometry_SPA).STEnvelope().STPointN(1).STX,0,1) AS XLO,
ROUND(geometry::UnionAggregate(Geometry_SPA).STEnvelope().STPointN(1).STY,0,1) AS YLO,
ROUND(geometry::UnionAggregate(Geometry_SPA).STEnvelope().STPointN(3).STX,0) AS XHI,
ROUND(geometry::UnionAggregate(Geometry_SPA).STEnvelope().STPointN(3).STY,0) AS YHI
FROM State;
If you are using SQL Server 2008 R2, you would have to do it this way:
WITH
ENVELOPE as
(
SELECT Geometry_SPA.STEnvelope() as envelope from State
),
CORNERS as
(
SELECT envelope.STPointN(1) as point from ENVELOPE
UNION ALL select envelope.STPointN(3) from ENVELOPE
)
SELECT
ROUND(MIN(point.STX),0,1) as XLO,
ROUND(MIN(point.STY),0,1) as YLO,
ROUND(MAX(point.STX),0) as XHI,
ROUND(MAX(point.STY),0) as YHI
FROM CORNERS;
Either way the results are the same. For this particular dataset, all the data is inside the state
boundary so the optimal bounding box is:
Otherwise, you would have to run the bounding box calculation for every feature class.
Page 43
Working with SQL Server Spatial
Lessons
2. Since we now know the bounding box parameters to use, update GParameters with this
information:
Update GParameters set GVALUE=360678 where GPARAMETER='XLowerBound';
Update GParameters set GVALUE=3340758 where GPARAMETER='YLowerBound';
Update GParameters set GVALUE=698922 where GPARAMETER='XUpperBound';
Update GParameters set GVALUE=3874594 where GPARAMETER='YUpperBound';
Commit;
3. Knowing the optimal bounding is a start, but you also need to know the distribution of the data
within the bounding box and in some cases, it may be more optimal to not include outliers. Prior to
SQL Server 2012, there were no tools to analyze the distribution of data in a spatial index so this was
really a trial and error process. With SQL Server 2012, you can run the following at different
resolutions to get the distribution of data within the index grid based on the bounding box:
The results show the intersection of features with the provided grid resolution (32 in this case) and
the spatial results gives you an idea of how the index grid lays out:
Page 44
Working with SQL Server Spatial
Lessons
The most efficient spatial indexes will have a large percentage of the records being determined from
the primary and internal filters with very few outliers that have to be checked individually. You also
want to balance the number of grid cells with the number of records being returned. Too many cells
can make the index too large to be efficient, while too few cells make the secondary filter work
harder.
This is a difficult balance to determine in SQL Server 2008 but in SQL Server 2012, the grid resolution
is balanced for you via GEOMETRY_AUTO_GRID.
4. Create a spatial index on State, Counties, and Roads_Primary using the following:
CREATE SPATIAL INDEX [STATE_SIDX] ON [dbo].[State]([Geometry_SPA])USING
GEOMETRY_AUTO_GRID
WITH (BOUNDING_BOX =(360678, 3340758, 698622, 3874594),
CELLS_PER_OBJECT = 16) ON [PRIMARY]
GO
CREATE SPATIAL INDEX [Counties_SIDX] ON [dbo].[Counties]([Geometry_SPA])USING
GEOMETRY_AUTO_GRID
WITH (BOUNDING_BOX =(360678, 3340758, 698622, 3874594),
CELLS_PER_OBJECT = 16) ON [PRIMARY]
GO
CREATE SPATIAL INDEX [Roads_SIDX] ON
[dbo].[Roads_Primary]([GDO_Geometry_SPA])USING GEOMETRY_AUTO_GRID
WITH (BOUNDING_BOX =(360678, 3340758, 698622, 3874594),
CELLS_PER_OBJECT = 32) ON [PRIMARY]
GO
Page 45
Working with SQL Server Spatial
Lessons
Goals
1. In the Management Studio, expand the Denmark database and then expand tables.
2. Right click on Airports and select Design.
3. Add a new column called Geometry_gdo and make the data type varbinary(MAX):
The column name does not really matter but it is useful to make it reflect the current geometry
name so that it is easier to make the required association later when metadata is added. To Save
the change, select the X on the tab next to the table's name. Then answer Yes when prompted.
4. You can use the Design method or just use an alter table statement in SQL. Right click on Denmark
and select New Query. Execute the following:
Alter table CitiesWGS add Geography_GDO varbinary(MAX);
To verify the change, right click on CitiesGWS and select Refresh. Then expand Columns,
Geography_GDO should appear in the list. Since it would be tedious to do this to all the tables, just
copy and paste the following in the query window to process the rest:
Page 47
Working with SQL Server Spatial
Lessons
b. Select Airports from the insert list and then select the Properties button.
c. On the Feature Class Properties dialog, select the Attributes tab and review the information
there. Since the primary key column is identity based, set its DataType to autonumber. This
will make GeoMedia automatically use the identity increment. You will get a warning here:
The warning is just a reminder to set the identity property in Management Studio or to not
use autonumber. In our case, the identity property has been set to you can ignore this
warning. Select check box not to display the message again and then select OK.
d. Select the Geometry tab. The Field Name should be automatically associated with the
varbinary(max) column Geometry_gdo.
e. Set the Geometry Type for Airports to SpatialPoint.
f. Select the native spatial Geometry column and then set the Native SRID to Projected (SRID
0). See below for an example of how this should look:
Page 48
Working with SQL Server Spatial
Lessons
Another warning will be issued telling you that the selected coordinate system will be applied to all
feature classes in the list. If you had included EuropeWGS, the wrong coordinate system would
have been assigned. How would you fix this?
Page 49
Working with SQL Server Spatial
Lessons
7. Select Insert Feature Class Metadata again and add EuropeWGS to the list at right. Select
EuropeWGS and then select Properties.
a. On the Attributes tab, set the Data Type to autonumber.
b. On the Geometry tab, set the Geometry Type to SpatialArea, then set the Native Geometry
and SRID, in this case, the SRID is WGS84 – EPSG:4326.
c. Select Ok to continue, and then select OK on the Insert Feature Class Metadata dialog.
d. You are prompted to assign a coordinate system but the default CS is not the correct one to
use. Select the New button and the select Load. Navigate to C:\SQLWorkshop\Data and
select Geographic – WGS84.csf. This should show up in the list as Geographic, Assign this
one but DO NOT make it the default.
8. Select the Assign Coordinate System button to see how the coordinate systems are assigned. This is
the only place you can change a coordinate system (without affecting the actual data) that has been
incorrectly assigned:
9. Since the assignments are correct, select Cancel and then select Close on the Database Utilities
dialog, we will come back to that later.
10. As a last step, remember to set the defaults you want to use for this schema in the GParameters
table. Since the Denmark data is projected, the only parameters you need to worry about are the
bounding box ranges. You can leave the default bounding box as it is but you should calculate an
appropriate bounding box to use based on what you have learned already (page 49).
Page 50
Working with SQL Server Spatial
Lessons
There are two maintenance triggers that are required for each feature class. One handles inserts and
the other handles updates. The triggers are essentially the same for every feature class; they only differ
in the table name and the names of the primary key column, native spatial column, and GDO geometry
column for the table. You need the following information from the table:
<tablename> : The table the trigger applies to.
<native_geom> : The native spatial geometry column name.
<GDO_geom> : The GDOgeometry (varbinary(MAX) column name.
<key_col> : The name of the primary key column.
The INSERT trigger looks for an insert operation on the GDO column without a corresponding insert on
the native geometry column. If this occurs, the edit is disallowed and a rollback occurs. An insert
operation on just the native geometry or on both geometries is allowed. Here is the syntax for the
insert trigger:
CREATE TRIGGER [dbo].[<tablename>_ins] ON [dbo].[<tablename>] AFTER INSERT AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM INSERTED WHERE INSERTED.[<native_geom>] IS NULL
AND INSERTED.[<GDO_geom>] IS NOT NULL)
BEGIN
RAISERROR ('Unsupported operation on GDO column.', 0, 1);
ROLLBACK TRANSACTION;
END;
END;
GO
The UPDATE trigger looks for an update operation on the native geometry column without a
corresponding update on the GDO column. If that occurs, the trigger writes a NULL to the GDO
geometry, effectively clearing it. If the GDO column is updated without a corresponding update to the
native geometry column, the transaction is rolled back. Here is the syntax for the update trigger:
CREATE TRIGGER [dbo].[<tablename>_upd] ON [dbo].[<tablename>] AFTER UPDATE AS
BEGIN
SET NOCOUNT ON;
IF UPDATE([<native_geom>])
BEGIN
IF NOT UPDATE([<GDO_geom>])
BEGIN
UPDATE [<tablename>] SET [<GDO_geom>] = NULL
WHERE EXISTS (SELECT NULL
FROM INSERTED WHERE INSERTED.[ID] = [<tablename>].[<key_col>]);
END;
END;
ELSE IF UPDATE([<GDO_geom>])
BEGIN
RAISERROR ('Unsupported operation on GDO column.', 0, 1);
Page 51
Working with SQL Server Spatial
Lessons
ROLLBACK TRANSACTION;
END;
END
GO
By just substituting the information for each table into the above trigger statements, you can create the
maintenance triggers you need. Create the maintenance triggers for the Airports table.
Since the maintenance triggers are generally the same, it is an easy process to run as a stored
procedure. That will be demonstrated in the next Lesson.
Spatial Filters
When working with very large datasets, you should always use Spatial Filters. Trying to display millions
of records in a GeoMedia map window will kill performance and the resulting display will just be a mess
of data. The real power of working with native spatial data is the ability to filter the data by a specific
geographic area. GeoMedia offers four filter options; Coarse Overlap, Overlap, Inside, and Entirely
Page 52
Working with SQL Server Spatial
Lessons
Inside. Using spatial filter reference features can also be useful as a way to use regional areas to work in
and these are not affected by spatial filters in the map display.
b. Spatial reference features are exempt from spatial indexing in the map window and can be
used as spatial filter areas. They can be very useful if you have regional areas that you
regularly display and work in. Select Ok to continue.
4. Select Legend>Add Legend entries and expand Reference features. Under DenmarkSpatial, select
Denmark and then select OK. The Denmark class should be added to the legend.
5. Select Legend>Add Legend entries and select all the feature classes under DenmarkSpatial except
for Denmark:
6. When you select OK, the result should be similar that that shown below, if you do not see this or are
zoomed way out, right click on the legend entry Denmark and select Fit By Legend Entry:
Page 53
Working with SQL Server Spatial
Lessons
8. The fewer the vertices in the filter area used, the faster it will be, so if you are after performance,
use a rectangular fence. Create a fence filter around the city of Copenhagen and follow the prompts
to press the query:
9. The default filter method is Inside, which will include everything inside up to and including the
boundary. This is using SQL Server's STWithin operator. To change the filter method to a faster
operator, select the Spatial Filter Options button on the filter toolbar and then change the Spatial
Operator to Coarse Overlap. Select Ok to process the query.
10. Does the filter performance appear to be a bit slow? Check whether you have a spatial index on the
Roads table, likely one does not exist. The filters work whether a spatial index is present or not,
Page 54
Working with SQL Server Spatial
Lessons
they are just very slow when the index is missing. Create a spatial index on Roads via the
Management Studio; you should know how to do this by now. I would use the bounding box for
Denmark. Once you do this, the filters should be very fast.
11. To fit the filtered area, select the Fit Spatial Filter button:
12. Create a circular filter in a location similar to what you see above (red arrow). You have a variety of
options with spatial filters:
13. To remove the spatial filter, select the remove filter button. The right-click on the legend entry
Denmark and select Fit by Legend Entry.
14. One of the benefits of having spatial filter reference features is that you can also use those to create
spatial filter areas. For example, if you need to work on all the Roads in LOLLAND, you can filter just
on that region. On the spatial filter toolbar, select the Select Reference Features button.
a. On the Select Reference Features dialog, select Denmark from the list of Reference Features.
b. Change the Feature Name Attribute to Name and then select the Show Values button. This
will list the named areas to choose from.
c. Choose LOLLAND (DENMARK) from the list and select OK to process the query:
Page 55
Working with SQL Server Spatial
Lessons
d. Select the Fit Spatial Filter button to zoom in on the region you chose:
15. You can name this spatial filter area as well. Select the Named Spatial Filters button from the Filter
Toolbar and then select the Name button. Name the filter LOLLAND and then select Apply. The
active named filter will be displayed and you can close the dialog.
16. You can change the filter options on the fly so experiment with some of the other filter types before
moving to the next section.
Functional Attributes
Most of the operations in GeoMedia work the same regardless of the read-write data server being used.
The exception is the use of Functional Attributes (which also affects the Update Attributes command).
In this case, the only geometry column exposed is the GDO geometry; the native geometry is not visible.
Any operations using Functional Attributes will still work; you just have to remember to use the GDO
column. Here is a quick example:
8. To demonstrate the change to Update Attributes, we first need to add a new column to the Airports
feature class. Select Warehouse>Feature Class Definition:
a. Select Airports on the Feature Class Definition dialog and then select Edit.
b. Select the Attributes tab, and then add a new column called SymbolRotation using the
Double data type:
Page 57
Working with SQL Server Spatial
Lessons
c. Select OK when complete and then Close the Feature Class Definition dialog.
9. Select Edit>Attribute>Update Attributes.. from the menu:
a. Expand DenmarkSpatial and select the Airports feature class
b. Select the value for SymbolRotation and then select the Expression button.
c. From the Categories list, select Geometry.
d. From the Functions list, double click on Orientation (it will be added to the Expression list).
e. From the Attributes list, double click on the Input.Geometry_GDO.
f. Select OK to accept the expression. The Update Attributes dialog should look like the
following:
Page 58
Working with SQL Server Spatial
Lessons
g. Select Apply to update the SymbolRotation attribute with the Point geometry's rotation
angle. When the processing is complete, select Close.
10. Select Window>New Data Window to display the update made in step 9. Select Airports from the
DenmarkSpatial connection in the list AND THE Data Window will display. Keep in mind that your
spin value may differ from the ones shown below.
This is one method you could use for points to preserve the rotation of the point features while still
allowing edits to point geometries outside of GeoMedia.
Page 59
Working with SQL Server Spatial
Lessons
Goals
Spatial views must also include both the native spatial column and the GDO geometry column and this
information must also be reflected in metadata just a like a normal table. If you are constructing native
geometries on the fly in the view, keep in mind you will still need the GDO geometry column even if it's
just a NULL value.
1. In SQL Server Management Studio, open a new query window on your Denmark database. Execute
the following to create a simple view is one that involves just one table:
Create view Sonderborg as
SELECT PID, Geometry, Geometry_GDO FROM Denmark where Name = 'SONDERBORG';
Notice that I included both geometry columns and the primary key column. These are all required
to be successful with views.
2. One common request that comes in is to take a table that has Easting and Northing attribute
columns and dynamically convert them to native point geometry via a view. The same process could
be done with GPS based longitude/latitude data. The easiest way to do this is to use the POINT
method and here is an example (using just a select), but this will not work as a view in
GeoMedia…any ideas as to why?
SELECT PlaceID, Name , type, population,
Geometry::Point(Easting, Northing, 0) AS Geometry,
CAST(NULL AS varbinary(MAX)) AS Geometry_GDO
FROM Places;
Page 60
Working with SQL Server Spatial
Lessons
The reason this will not work is that GeoMedia requires 3D data and the POINT method only creates
2D point geometry. Instead, you have to use the following which makes the view definition a little
more complex. Execute the following to create the PopulatedAreas view:
Create view PopulatedAreas AS
SELECT PlaceID, Name , type, population,
Geometry::STPointFromText('POINT(' + CAST(Easting as nvarchar) + ' ' +
CAST(Northing as nvarchar) +' 0)', 0) AS Geometry,
CAST(NULL AS varbinary(MAX)) AS Geometry_GDO
FROM Places;
This works because you can assign a default z value (in this case 0). Because the easting and
northing values use a DOUBLE data type, they have to be converted to character to work in the
STPointFromText method. The addition of the GDO geometry is required to make the view work in
GeoMedia but it does not have to be populated (which is why it's created as NULL). Keep in mind
that editing this view in GeoMedia will fail unless you have an instead of trigger defined to handle
the insert, update and delete operations. What other is downside to this type of view?
3. You can also create dynamic views that use spatial functions. STBuffer, STCentroid, and
STPointOnSurface are all commonly used in views but any of the methods could be used here. Here
is a view that creates a 100m buffer zone around Railways.
CREATE VIEW RailwaysBuffer AS
SELECT PID, Name, type,
Geometry.STBuffer(100) as GeomBuffer,
CAST(NULL AS varbinary(MAX)) AS GeomBuffer_GDO
FROM Railways;
Again, notice the use of the NULL varbinary(MAX) column. This is required every time you create a
dynamic native geometry and want to use it in GeoMedia.
4. A join view just combines information from 2 or more columns. Spatial analysis views are good
examples of joins, but joins can be any combination of attributes and geometries. In this example,
you are finding all the motor way junctions that match road names and are within Sjaelland:
Create view Sjaelland_Road_Junctions AS
SELECT b.RoadPt_ID, a.name as Road, b.Geometry, b.Geometry_GDO
FROM roads a, roadpts b, Denmark c
WHERE a.name=b.name
and b.type='motorway_junctio'
and c.Name='SJAELLAND'
and b.Geometry.STWithin(c.geometry)=1;
5. During an earlier Lesson, you created a view called SjaellandRoads. Can you use this view with
GeoMedia? What's missing and how would you correct the problem?
good idea if the view contains a large amount of data. You should always allow for a key column to be
used with the view.
1. To use the views in GeoMedia, you will need to add metadata via Database Utilities or using the
stored procedures in GMPSpatialUtilities. Here is how to configure the metadata for the views
PopulatedAreas and RailwaysBuffer via Database Utilities:
2. Open Database Utilities and connect to your Denmark database.
3. Select the Insert Feature Class Metadata button.
4. Add PopulatedAreas and RailwaysBuffer to the Feature Classes to insert list.
5. Select PopulatedAreas from the list and then select Properties.
6. On the Attributes tab, set the PlacesID datatype to autonumber and then select the Select Primary
key for view button. This will make PlacesID the preserved key column.
7. On the Geometry tab, set the geometry type to SpatialPoint, set the Native Geometry to Geometry
and the Native SRID to Projected (SRID 0):
GMPSpatialUtilities
To help people get started with spatial data in Oracle, we delivered a package called GOOM containing a
lot of utilities to help manage spatial data and its metadata. While we cannot use packages in SQL
Server, we can use stored procedures and have a similar set of utilities that you can use here. The
collection is called GMPSpatialUtilities. It is freely avaiLessonle from the Web based support site and is
also included in your Lesson material.
Page 62
Working with SQL Server Spatial
Lessons
These stored procedures are considered open source and you are free to use and modify them to suit
your needs. They are unofficial so if you have questions or problems, you need to email me directly at
chuck.woodbury@intergraph.com. Do not file a support ticket on these stored procedures. You can also
email me if you see a need for a particular utility that can be addressed here; I am always open to
adding new stored procedures as long as they are relevant for general use.
Here is how to install and use the stored procedures in GMPSpatialUtilities with your database:
1. In the SQL Server Management Console, right click on your Denmark database and select New
Query.
2. Navigate to the C:\SQLWorkshop\Scripts directory and drag the GMPSpatialUtilities.sql file into the
new query window.
3. Select Execute to load the stored procedures, and then close the query window.
4. In a new query windows, execute the following:
EXEC GMPHelpme;
And the current set of procedures will be listed. The stored procedures are broken up into
categories based on their area of operation.
5. Since I regularly make updates to this collection, knowing the version you are using is useful
especially when you have questions or are reporting an issue. To get the version and date of the
current collection, execute:
EXEC GMPVersion;
Remember to include this information in any correspondence if you have questions or bugs to
report.
6. If you do not want to directly edit GParameters, you can use the stored procedures in the Defaults
category to change the default database settings used by GeoMedia. The most commonly use
procedure here is GMPSetDefaultMBR which will set the default bounding box used when
GeoMedia creates spatial indexes. This same bounding box is also used when creating indexes via
GMP stored procedures.
EXEC GMPCalculateMBR Denmark;
Bounding box for Denmark.Geometry: XLO= 441704 YLO= 6050158 XHI= 892874 YHI= 6401849
a. You could then use the above values to set the bounding box for Denmark as the default for
the database:
EXEC GMPSetDefaultMBR 441704, 6050158, 892874, 6401849
7. Grids are useful for very large data as a way to select working areas for coarse filters. Execute the
following to divide the bounding box parameters for Denmark into a 10X10 grid and store the
results in Denmark_Grid:
Page 63
Working with SQL Server Spatial
Lessons
The grid procedure creates individual area features so be careful of the parameters you use as this
can create a large number of features. The grid procedure automatically adds the grid table to
metadata and creates a spatial index so the result is a feature class that is ready to use in GeoMedia.
8. To see how the cells overly the Denmark feature class, execute the following:
select grid_cell from denmark_grid
union all
select geometry from Denmark;
9. To generate a spatial index on a table based on the bounding box stored in GParameters, you can
run the following:
EXECUTE GMPCreateSpatialIndexOn Denmark;
10. Or you can spatially index all the tables in the schema by executing:
EXECUTE GMPCreateSpatialIndexes;
Tables that already have spatially indexed will be skipped. If you want to recreate the index, you
need to drop it first. For that, you can use:
EXECUTE GMPDropSpatialIndexOn @TableName -- To drop the spatial index for a single table.
EXECUTE GMPDropSpatialIndexes -- To drop all spatial indexes in the database or
11. Stored procedures are also avaiLessonle for setting the SRID. For projected data, this is generally
not an issue since the SRID is 0 but for geographic data, you may need to set the SRID to the correct
value if it was not set correctly when the table was created.
a. For a single table you can use EXECUTE GMPSetSRIDOn @TableName, @SRID, for example:
b. You can also set the SRID for all tables in the schema using EXECUTE GMPSetSRIDAll @SRID
but only use this if you know all the tables use the same coordinate system or are all
projected.
12. Earlier in the Lessons, we manually created a maintenance trigger on the Airports feature class.
Execute the following to create the maintenance triggers via a stored procedure for the remaining
tables:
EXECUTE GMPCreateGDOTriggersOn CitiesWGS;
EXECUTE GMPCreateGDOTriggersOn Denmark;
EXECUTE GMPCreateGDOTriggersOn EuropeWGS;
EXECUTE GMPCreateGDOTriggersOn Lakes;
EXECUTE GMPCreateGDOTriggersOn NatuaralAreas;
EXECUTE GMPCreateGDOTriggersOn Railways;
EXECUTE GMPCreateGDOTriggersOn RoadPts;
EXECUTE GMPCreateGDOTriggersOn UrbanAreas;
EXECUTE GMPCreateGDOTriggersOn WaterWays;
You can verify that the trigger exists by right clicking on the database name and selecting Refresh.
Expand a table and then expand triggers and look for an INS and UPD trigger.
13. There are a couple of different ways to assign metadata for a table. If the table is already
populated, you just have to supply the table name. If the table is empty, you will need to provide
extra information about the table that would normally be picked up from the data itself. The syntax
for populated tables is
EXECUTE GMPSetMetadataFor @TableName
And for empty tables, or tables that do not use the default coordinate system:
EXECUTE dbo.GMPSetMetadataFor @TableName, @GeomType, @CSGUID, @SRID
Try these examples:
14. If the table is a different coordinate system, you would need to first determine the coordinate
system to use and then supply the CSGUID and SRID. Here is an example for CitiesWGS and
RailRoadsWGS:
Page 65
Working with SQL Server Spatial
Lessons
And use the resulting CSGUID for Geographic (yours may be different):
15. Views are similar to table except you need to specify the pseudo key column. Here are examples to
try for the Sonderberg and Sjaelland_Road_Junction views:
EXECUTE dbo.GMPSetMetadataFor 'Sonderberg', NULL, NULL, NULL, 'PID'
EXECUTE dbo.GMPSetMetadataFor 'Sjaelland_Road_Junctions', NULL, NULL,
NULL, 'RoadPt_ID'
16. To get the metadata listing for a table or view, use the syntax:
EXECUTE GMPListMetadataFor @TableName
--------------------------------------------------------------------------------------
-- GDO metadata for table: Denmark
......................................................................................
GFeatures
-> PrimaryGeometryFieldName.........Geometry_GDO
-> GM GeometryType..................2
AttributeProperties
-> PID
Key?: 1 Displayed?: 1 Type: 4 Precision: 0 Format: General Number
-> Name
Key?: 0 Displayed?: 1 Type: 10 Precision: 0 Format:
GeometryProperties
-> Geometry_GDO
Geometry Type: 2 Primary?: 1 CS: EA4D5344-324D-4598-98D5-99130ECE6F73
GFieldMapping
-> Geometry_GDO
Datatype: 32 Subtype: 2 AutoInc?: 0 Native Geometry: Geometry Native SRID: 0
-> PID
Datatype: 4 Subtype: AutoInc?: 1 Native Geometry: Native SRID:
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- GDO metadata for table: Sonderberg
......................................................................................
GFeatures
-> PrimaryGeometryFieldName.........Geometry_GDO
Page 66
Working with SQL Server Spatial
Lessons
-> GM GeometryType..................2
AttributeProperties
-> PID
Key?: 1 Displayed?: 1 Type: 4 Precision: 0 Format: General Number
GeometryProperties
-> Geometry_GDO
Geometry Type: 2 Primary?: 1 CS: EA4D5344-324D-4598-98D5-99130ECE6F73
GFieldMapping
-> Geometry_GDO
Datatype: 32 Subtype: 2 AutoInc?: 0 Native Geometry: Geometry Native SRID: 0
-> PID
Datatype: 4 Subtype: AutoInc?: 1 Native Geometry: Native SRID:
GIndexColumns
-> Sonderberg is a view.
IndexName: Sonderberg_GMIDX IndexColumn: PID Index Pos: 1 Index Type: P
------------------------------------------------------------------------------------
17. The ability to add and delete metadata from a script makes it easier for a DBA to make DDL changes
to tables. For example, if you want to add a new column a table, you would first want to delete the
metadata, then add the column, then add the metadata again. Here is an example of adding a new
column to the Waterways table:
EXECUTE GMPDeleteMetadataFor Waterways;
ALTER TABLE Waterways ADD AvgDepth FLOAT;
EXECUTE GMPSetMetadataFor Waterways;
The new column will be included when the metadata is added back. The only downside to this
method is that you cannot customize the metadata; it will only set the default. If you want to do
specific customization, you will have to use Database Utilities.
18. If you need to drop a table, keep in mind that doing so will leave its metadata orphaned. You should
delete the metadata before dropping the data. To do both operations are the same time, you can
use the following:
EXECUTE GMPDeleteTable @TableName
This will delete the associated metadata before dropping the specified table.
19. Two other utility commands are avaiLessonle:
EXECUTE GMPChangeOwner2DBO
EXECUTE GMPNullZeroLength
These operate on all the tables and views in the database but are rarely required anymore.
GMPChangeOwner2DB ensures that all tables and views are owned by dbo, which is required by
GeoMedia. GMPNullZeroLength solves an old problem where zero length line strings '' were treated
Page 67
Working with SQL Server Spatial
Lessons
as a string rather than a NULL. This was a common problem in SQL Server 2005 but only affects
legacy data now.
You can use the stored procedures in GMPSpatialUtilities if you need them but they are not required to
work with spatial data. Feel free to make additions and modifications to these utilities if you need to. I
will periodically post updates and bug fixes to the WEB, but if you run into any issues, please let me
know.
Modification Logging
If you want active GeoMedia sessions to be aware of changes made outside of GeoMedia via SQL or
some third part application, you need to assign modification log triggers to the feature classes. This
allows changes to be logged to ModificationLog metadata table. In GeoMedia, anytime there is a map
window refresh, the ModificationLog table is read and any changes are incorporated into the view. You
can also force a refresh by selecting the Refresh with Warehouse Changes command which will allow
you to see changes made by other users while you are in a GeoMedia session. This is very important
when editing via views since the actual change being made is to the base table.
3. Open GeoMedia, create a new workspace, and make a connection to the Denmark database.
4. Add Waterways and Rivers to the legend.
Page 68
Working with SQL Server Spatial
Lessons
5. Select insert feature class from the toolbar, and select Rivers. Digitize a river similar to that below,
remember to set the RiverType attribute to river:
Notice that the number of Rivers on the legend increases by one but the Waterways feature class
remains the same. This is because a ModificationLog entry was written for Rivers but not for
Waterways. GeoMedia has no way of knowing that the Waterways feature class has changed.
6. The only way to see the update to Waterways in this scenario is to reopen the connection. Select
Warehouse> Connections and then select the Reopen Connection button. The number of features
shown for Waterways should increase to 1001.
7. To solve this issue, you need to add modification log triggers to the Waterways table. For now, you
will need to create three triggers; one for insert, update and delete. Here is the syntax to do this for
insert:
CREATE TRIGGER [dbo].[WaterwaysGMTI] ON [dbo].[Waterways] FOR INSERT AS SELECT @@identity
DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Waterways'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 1, convert(nvarchar(20),@TableID), convert(nvarchar(255),
inserted.[WaterwayID])
FROM inserted
END;
GO
Note the use of the inserted table here. Also, notice the naming convention, this is required. Insert
triggers must be tableGMTI, update triggers must be tableGTMU, and delete triggers must be
tableGMTD.
8. For the update trigger, use the following:
CREATE TRIGGER [dbo].[WaterwaysGMTU] ON [dbo].[Waterways] FOR UPDATE AS
DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Waterways'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
Page 69
Working with SQL Server Spatial
Lessons
SELECT 2, convert(nvarchar(20),@TableID),
convert(nvarchar(255), deleted.[WaterwayID]) FROM deleted
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 2, convert(nvarchar(20),@TableID),
convert(nvarchar(255), inserted.[WaterwayID]) FROM inserted
END;
GO
Why do you have to handle both the insert and the delete for updates?
10. Now go back into GeoMedia, reopen the Denmark connection and insert another River feature.
This time, notice that the Waterways feature was automatically updated. The Modification Log
triggers are handling that. Similarly with a delete; delete both of the River features you have added
by selecting them and then selecting Delete Feature from the editing tool bar:
Page 70
Working with SQL Server Spatial
Lessons
Again, you should see the features disappear in both Rivers and Waterways.
11. So, adding the Modification Log triggers to Waterways solves the update issue but what happens is
you edit Waterways and insert a river type? Select insert feature class and then select Waterways
from the drop down and digitize a Waterways feature. Name the feature Chuck, set the type to
rivers, and then select OK:
Notice that Waterways legend entry increments by 1 but Rivers do not. Why did this happen and
how do you solve it?
12. GeoMedia does not know of a change to Rivers, it only knows that Waterways has changed. To
solve this, you need to update the Modification Log triggers for Waterways to include an entry for
the view. Right click on the WaterwaysGMTI trigger and select Modify. Then add the section for
the view as shown below. Execute the query when you have made the change:
ALTER TRIGGER [dbo].[WaterwaysGMTI] ON [dbo].[Waterways] FOR INSERT AS
DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Waterways'
Page 71
Working with SQL Server Spatial
Lessons
13. To complete the whole process, you need to modify the update and delete triggers as well.
a. Right click on the WaterwaysGMTU trigger and select Modify. Then add the section for the
view as shown below. Execute the query when you have made the change:
ALTER TRIGGER [dbo].[WaterwaysGMTU] ON [dbo].[Waterways] FOR UPDATE AS
DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Waterways'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 2, convert(nvarchar(20),@TableID),
convert(nvarchar(255), deleted.[WaterwayID]) FROM deleted
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 2, convert(nvarchar(20),@TableID),
convert(nvarchar(255), inserted.[WaterwayID]) FROM inserted
-- Added for view:
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Waterways'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 2, convert(nvarchar(20),@TableID),
convert(nvarchar(255), deleted.[WaterwayID]) FROM deleted
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 2, convert(nvarchar(20),@TableID),
convert(nvarchar(255), inserted.[WaterwayID]) FROM inserted
END;
GO
b. For the delete trigger, right click on the WaterwaysGMTD trigger and select Modify. Then
add the section for the view as shown below. Execute the query when you have made the
change:
ALTER TRIGGER [dbo].[WaterwaysGMTD] ON [dbo].[Waterways] FOR DELETE AS
DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Waterways'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 3, convert(nvarchar(20),@TableID),
convert(nvarchar(255), deleted.[WaterwayID])
FROM deleted
-- Added for the view
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Rivers'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 3, convert(nvarchar(20),@TableID),
convert(nvarchar(255), deleted.[WaterwayID])
FROM deleted
END;
GO
14. Test the process in GeoMedia. Close and reopen the connection to Denmark and insert a new I
feature, make sure you change the type to river:
Page 73
Working with SQL Server Spatial
Lessons
Notice that both feature classes are now updated on the legend.
15. Press the ESC key to exist the insert feature class mode. Hover the mouse arrow over the newly
inserted feature and you should see … when you do click the left mouse button and the PickQuick
dialog will pop up showing that you have two features, Waterways and Rivers. Select the PickQuick
button associated with Waterways and the Waterways feature is highlighted.
16. Select the Delete feature button from the toolbar and both features should disappear. The
Modification Log triggers are in action.
17. Modification Triggers can be tedious to set up but there is a procedure for it in GMPSpatialUtilities.
To create Modification Log triggers for the Denmark feature class, just run the following:
EXECUTE GMPCreateModLogTriggerOn Denmark
18. To verify the creation, right click on the Denmark table and select Refresh, then the table and the
Triggers. You should see the triggers in the list:
There is currently no automated way of adding a view to a modification log trigger so that is still a
manual process but it is important if you are trying to edit via views.
Page 74
Working with SQL Server Spatial
Lessons
The information contained in this document (the “Work”) is the exclusive property of Intergraph Corporation (“Intergraph”). The Work is protected under
United States copyright law and other international copyright treaties and conventions, to include the Berne and Geneva Phonograms Conventions, the
WIPO Copyright Treaty, and the World Trade Organization.
No part of the Work may be reproduced, stored, or transmitted in any form or by any means, electronic or mechanical, including photocopying and
recording, or by any information storage or retrieval system, except as expressly permitted in writing by Intergraph. All such requests should be sent to
the attention of Manager of Customer Education of the Hexagon Geospatial Division of Intergraph (“Hexagon Geospatial”) at the following address:
Hexagon Geospatial
5051 Peachtree Corners Circle
Norcross, Georgia 30092-2500 USA
Page 75