0% found this document useful (0 votes)
32 views73 pages

Working with SQL Server Spatial - Lessons1

Training Manual SQL Server

Uploaded by

nasiralimengal
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
32 views73 pages

Working with SQL Server Spatial - Lessons1

Training Manual SQL Server

Uploaded by

nasiralimengal
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 73

GeoMedia 2015

Working with SQL Server Spatial


Lessons
January 2015
Working with SQL Server Spatial
Lessons

CONTENTS

Contents ..................................................................................................................................... 4

Workshop Preparation ............................................................................................................... 5

Lesson 1: Working with Spatial tables ........................................................................................ 6

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

Lesson 2: Spatial Queries, Indexing and Analysis ...................................................................... 15

Loading Native Spatial Test Data ......................................................................................... 15


Querying Geometry Components ........................................................................................ 16
Creating Spatial Indexes ...................................................................................................... 19
Analyzing Spatial Data ......................................................................................................... 21
Spatial Functions ................................................................................................................. 24
Aggregations in SQL Server 2012 ......................................................................................... 25

Lesson 3: Using GeoMedia ........................................................................................................ 27

Creating a GeoMedia Database ........................................................................................... 27


Setting GeoMedia Defaults.................................................................................................. 29
Using Feature Class Definition ............................................................................................. 33
Basic Editing and Maintenance Triggers .............................................................................. 36
Export/Import Operations ................................................................................................... 39
Output to Feature Class....................................................................................................... 41
Optimizing Indexes .............................................................................................................. 43

Lesson 4: Converting Existing Data ........................................................................................... 46

Adding Required Columns ................................................................................................... 46


Creating and Updating Metadata ........................................................................................ 47
Creating Maintenance Triggers............................................................................................ 51
Spatial Filters ...................................................................................................................... 52
Functional Attributes........................................................................................................... 56

Lesson 5: Views, Logging, and Utilities ...................................................................................... 60

Working with Views ............................................................................................................ 60


Views and GeoMedia's Metadata ........................................................................................ 61
GMPSpatialUtilities ............................................................................................................. 62
Modification Logging ........................................................................................................... 68

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.

This directory contains the following:

 Data: Sample data sets used in the workshop.


 Scripts: Scripts and stored procedures used by this workshop.
 Lessons.sql: The SQL used in the workshop Lessons
 SQL Server Spatial Data Server - Lessons: Hands on portion of workshop
 SQL Server Spatial Data Server - User Guide: Useful documentation.
 SQL Server Spatial Data Server - Workshop: The PowerPoint presentations.

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

LESSON 1: WORKING WITH SPATIAL TABLES


In this Lesson you will create and work with spatial tables in SQL Server. The goal here is to
understand how to use SQL Server spatial data types within the database. The first step will be to
create some databases that you can utilize for a most of the Lessons. DDL operations will step you
thru the creation of tables using spatial data types. The section on WKT/WKB introduces you to the
OGC well known text and well known binary formats. These formats can then be used for the DML
operations that follow. Once you have data loaded, the query section will show you some examples of
querying and analyzing the spatial data you have loaded.

Goals

 SQL Server coordinate systems


 Creating Tables (DDL)
 Using WKT and WKB
 DML Operations with spatial data
 Querying Spatial data

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:

SQL Server Coordinate Systems


Each column containing spatial data has a spatial reference identifier (SRID). The SRID corresponds to a
spatial reference system based on the specific ellipsoid used for either projected mapping or geodetic
mapping. A spatial column can contain objects with different SRIDs but only spatial instances with the

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:

SELECT * FROM sys.spatial_reference_systems;

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:

SELECT * FROM sys.spatial_reference_systems


WHERE spatial_reference_id=25832;

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:

GEOGCS["WGS 84", DATUM["World Geodetic System 1984", ELLIPSOID["WGS 84", 6378137,


298.257223563]], PRIMEM["Greenwich", 0], UNIT["Degree", 0.0174532925199433]]

which is a common geographic world coordinate system.


4. If you want to find the unit of measure used by a specific coordinate system, execute the following
query:

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

5. How many EPSG coordinate systems are avaiLessonle in SQL Server?

SELECT COUNT(*) from SYS.spatial_reference_systems;

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.

1. First, create a simple attribute table in SQL Server:


CREATE TABLE [dbo].[INGRCustomers] (
CustomerID int identity primary key,
FirstName nvarchar(50),
LastName nvarchar(50),
Country nvarchar(32));
Notice the use of an identity primary key, this will give you the best results and will automatically be
clustered. A clustered primary key is required for spatial data.
Then, add a geography column to it:

ALTER TABLE [dbo].[INGRCustomers]


ADD Location geography;

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:

ALTER TABLE [dbo].[INGRCustomers]


ADD CONSTRAINT [EnforceSRID_INGRCustomers]
CHECK (Location.STSrid = 4326);

3. You can also constrain the table to a specific geometry type:


ALTER TABLE [dbo].[INGRCustomers]
ADD CONSTRAINT [EnforcePoint_INGRCustomers]
CHECK (Location.STGeometryType() = 'POINT');

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

Using WKT and WKB Conversion Methods for DML operations


Well-known text (WKT) is a text markup language for representing vector geometry objects on a map. A
binary equivalent, known as well-known binary (WKB) is used to transfer and store the same
information on databases. Both SQL Server and Oracle support WKT and the formats are regulated by
the Open Geospatial Consortium (OGC) and described in their Simple Feature Access and Coordinate
Transformation Service specifications.

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));

4. So, what happens if you try to insert a line?

INSERT INTO INGRCustomers VALUES ('Chuck','Woodbury','USA',


geography::STLineFromText('LINESTRING(55 8, 57 10)', 4326));

You get a big error:

The INSERT statement conflicted with the CHECK constraint


"EnforcePoint_INGRCustomers". The conflict occurred in database "SpatialUser", table
"dbo.INGRCustomers", column 'Location'.

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

INSERT INTO INGRCustomers VALUES ('Chuck','Woodbury','USA',


geography::Point(55,10,4134));

Again, you get a constraint violation:

The INSERT statement conflicted with the CHECK constraint "EnforceSRID_INGRCustomers".


The conflict occurred in database "SpatialUser", table "dbo.INGRCustomers", column
'Location'.

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:

UPDATE INGRCustomers set Location = geography::Point(52,12,4326)


WHERE CustomerId=1;

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() );

8. Now for the inserts:


INSERT INTO SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0));
INSERT INTO SpatialTable (GeomCol1)
VALUES (geometry::STGeomFromText('POLYGON ((0 0, 150 0, 150 150, 0 150, 0 0))', 0));

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 :

SELECT * FROM SpatialTable;

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
)

b. In this example, you are creating a multipoint


geometry by first declaring a geometry
variable and then assigning it data. The last
step allows you to view the results:
DECLARE @ThreePoint geometry
SET @ThreePoint =
geometry::STMPointFromText(
'MULTIPOINT(783718 3447847,
784048 3448284, 783348 3447613)', 0)
INSERT INTO SpatialTable values
(@ThreePoint)
SELECT @ThreePoint

Could you have updated a record this way? Yes, here is the syntax:

Update SpatialTable SET GeomCol1 = @ThreePoint WHERE id =1;

c. This is an example of a multi-linestring. Notice how the different lines are in separate (…):

DECLARE @MultiLineString geometry


SET @MultiLineString = geometry::STMLineFromText(
'MULTILINESTRING((10 20, 3 4, 43 42),(44 10, 20 40))', 0)
INSERT INTO SpatialTable values (@MultiLineString);

Page 11
Working with SQL Server Spatial
Lessons

SELECT * FROM SpatialTable;

d. Here is a similar example of a multi-polygon:

DECLARE @MultiPolygon geometry


SET @MultiPolygon = geometry::STMPolyFromText(
'MULTIPOLYGON(((10 20, 30 40, 44 50, 10 20)),((5 0, 20 40, 30 34, 5 0)))', 0)
INSERT INTO SpatialTable values (@MultiPolygon);

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:

DECLARE @GeometryCollection geometry;


SET @GeometryCollection = geometry::STGeomCollFromText(
'GEOMETRYCOLLECTION(POLYGON((5 5, 10 5, 10 10, 5 5)), POINT(7.5 9.5))', 0)
INSERT INTO SpatialTable values (@GeometryCollection);
SELECT * FROM SpatialTable;

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):

DECLARE @MyLine geometry;


SET @MyLine = geometry::Parse('LINESTRING(12236.0 4765.6 0, 12234.3 4765.8 10)')
SELECT @MyLine

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()

Converting geometries back to WKT


Geometries are in binary format so once they are loaded it can be difficult to get a tabular
representation of the spatial data. SQL Server has several methods avaiLessonle for converting from the
Page 12
Working with SQL Server Spatial
Lessons

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():

SELECT id, GeomCol1.STAsText(), GeomCol1.STAsBinary() FROM SpatialTable;

4. You can also convert directly to GML using AsGml():

Page 13
Working with SQL Server Spatial
Lessons

SELECT id, GeomCol1.AsGml() FROM SpatialTable;

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.

This is the end of Lesson 1.

Page 14
Working with SQL Server Spatial
Lessons

LESSON 2: SPATIAL QUERIES, IND EXING AND ANALYSIS


In this Lesson you will create a small dataset that will better demonstrate query and indexing
capability. The goal is to understand how to extract information from a geometry or geography data
type, create spatial indexes, and perform basic spatial analysis on the data. The first step will be to
bulk load a small dataset that will allow us to get creative with our queries.

Goals

 Load native spatial test data


 Querying geometry components
 Creating Spatial Indexes
 Analyzing Spatial Data
 Spatial Functions
 Aggregations in SQL Server 2012
 Geography Considerations

Loading Native Spatial Test Data


In Lesson 1 you created a database called Denmark. There is a small test database backup file called
Denmark.bak in the C:\SQLWorkshops\data directory. The first step is to restore and use this backup.

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:

Velkommen til Danmark!

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).

Querying Geometry Components


Querying spatial enabled tables is no different than querying non-spatial tables except you can get a
graphic representation of the results as well as a tabular one. However, there may be times you need to
query the content of the spatial column itself and these require specialized methods. These types of
queries differ from spatial analysis queries in that a spatial index is not required for the query to be
performant.
Page 16
Working with SQL Server Spatial
Lessons

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;

This is new capability in 2012.


3. You cannot edit a single vertex of spatial data but you can manipulate the SRID's. This is most useful
in ensuring you have the correct SRID assigned to geographic data. For projected data, sometimes it
is enough just to make sure the SRID is set to 0.
a. Here is a quick query example, CitiesWGS uses geography in WGS84 so the SRID should be
4326:
SELECT DISTINCT( GEOM_POINT.STSrid ) FROM CitiesWGS;

Why use the DISTINCT operator here? Is it required or just useful?

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

a. These queries will return the distinct geometry types used:

SELECT DISTINCT(Geometry.STGeometryType() ) From Railways;


SELECT DISTINCT(Geometry.STGeometryType() ) From EuropeWGS;

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;

b. A similar query will work for geography base data:


SELECT GEOM_POINT.Long AS Longitude, GEOM_POINT.Lat AS Latitude,
GEOM_POINT.Z AS ELEV
FROM CitiesWGS;

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

c. How many total points make up this particular line segment?

SELECT Geometry.STNumPoints() FROM Railways WHERE PID=1;


Result: 19

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';

And if you want the 5th geometry stored, use:

SELECT Geometry.STGeometryN(5) FROM EuropeWGS WHERE Name='DENMARK';

8. Length and area calculations are also straight forward:


a. For the length of line strings, use .STLength(). Here is an example that finds the length of all
the railways:
SELECT Geometry.STLength() FROM Railways;

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'

Creating Spatial Indexes


The queries used above operated directly on the data and work correctly with or without a spatial index.
For queries involving spatial analysis, a good spatial index is required in order for the queries to be
performant. Without a spatial index, queries that should take just a few seconds may take hours to
process.

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:

CREATE SPATIAL INDEX [indexname] ON [dbo].[tablename]([Geometry])

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.

Analyzing Spatial Data


Spatial analysis generally involves analyzing a specific relationship between geometries in two different
tables to determine if the relationship is True (1) or False (0). No coordinate conversion occurs so the
data must either be projected (SRID=0) or use the same geographic SRID. Geographic calculations are
much more complicated, perform slower, and there are fewer analysis types avaiLessonle.

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

2. To refine this filter, try using the STWithin operator instead:


SELECT a.Name, a.geometry from UrbanAreas a, Denmark b
WHERE b.Name = 'SJAELLAND'
AND a.geometry.STWithin(b.geometry)=1

The results are very different.

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;

The result now is much better.


4. You can also look at the opposite results by just changing the comparison to False(0):
SELECT a.Name, a.geometry from UrbanAreas a, Denmark b
WHERE b.Name = 'SJAELLAND'
AND a.geometry.STIntersects(b.geometry)=0;

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

selects, you have to do this one a little differently:


DECLARE @geom geometry
SELECT @geom = geometry from UrbanAreas where name =
'COPENHAGEN'
SELECT Name FROM UrbanAreas where
geometry.STDistance(@geom) <=10000

6. Find all the Railways that cross UrbanAreas. You would use the

Page 22
Working with SQL Server Spatial
Lessons

following syntax here geometry1.STCrosses(geometry2) and the result should look


similar to:

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:

SELECT Count(*) from Denmark a, Roads b


WHERE b.ref='E20'
AND a.geometry.STContains(b.geometry)=1;

The answer is 42. But if you do the following:

Page 23
Working with SQL Server Spatial
Lessons

SELECT Count(DISTINCT(a.PID)) from Denmark a, Roads b


WHERE b.ref='E20'
AND a.geometry.STContains(b.geometry)=1;

The answer is 3. If you want distinct results returned graphically, do


the following:

SELECT geometry from Denmark where PID IN


(SELECT DISTINCT(a.PID) from Denmark a, Roads b
WHERE b.ref='E20'
AND a.geometry.STContains(b.geometry)=1);

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;

Zooming in on Copenhagen, you can see the buffer results 

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

4. STBoundary can be used to return the linestring boundary of a polygon:


SELECT geometry.STBoundary() from Denmark;

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;

Aggregations in SQL Server 2012


These aggregation functions were introduced in SQL Server 2012 so if you are not using SQL Server
2012, skip this section. Aggregate methods are useful when you need to combine geometry results into
a single all-encompassing geometry. Because these are methods and not functions, they require the full
specification depending on the geometry type being used. Here are some examples:

1. UnionAggregate() combines multiple spatial objects into a single object. Here is an example using
Denmark:

SELECT geometry::UnionAggregate(Geometry) FROM Denmark;

2. If you combine UnionAggregate with STEnvelope, you get an optimal bounding box
for use with a spatial index:

SELECT geometry::UnionAggregate(Geometry).STEnvelope() FROM Denmark;

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

POINT (441704.73411501746 6050158.7592739053)


POINT (892874.07064429729 6401848.8423584914)
And then round the result to integers:
441704, 6050159 to 892874, 6401849
How does this compare to the values we estimated? I will demonstrate an even better way to do
this later.

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;

5. CollectionAggregate is similar to UnionAggregate but in this case, the


geometries are combined into a geometry collection with each item in the
collection coming from each geometry instance in the original data:
SELECT geometry::CollectionAggregate(geometry).STAsText()
FROM Denmark;

In this case, the result is a multipolygon geometry collection.

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;

This is the end of Lesson 2.

Page 26
Working with SQL Server Spatial
Lessons

LESSON 3: USING GEOMEDIA


GeoMedia Professional is already installed on your Lesson system but the SQL Server spatial data
server is a separate add-on component. In the future, this will be incorporated as part of the core
application but for now, you will need to install it manually.

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

 Create a GeoMedia database


 Examine metadata tables
 Setting GeoMedia defaults
 Using Feature Class Definition
 Basic Editing and Maintenance Triggers
 Export/Import operations
 Output to Feature Class
 Optimizing Indexes

Creating a GeoMedia Database


In this section you will create a new SQL Server database that we can use with GeoMedia. We will use
this database to demonstrate some basic GeoMedia/database operations. After creating the database,
you will use Database Utilities to create the required metadata tables.

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:

Select Close where everything looks OK.

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

Setting GeoMedia Defaults


Though there may be times that you need to make manual changes to GeoMedia's metadata tables, it is
generally not a good idea to manually edit these tables. Many of the tables are inter-related and
changes to one needs to be reflected in the others. That is why you should use Database Utilities to
edit the data stored here. The exception is the GParameters table which contains the default setting
used by GeoMedia when creating and exporting tables to the database.

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

FUNCTION [dbo].[SqlGeometry2Binary] (@Blob geometry) RETURNS varbinary(max)


AS
BEGIN
RETURN CAST(@Blob AS varbinary(max));
END

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.

Using Feature Class Definition


Feature Class Definition (FCD) allows database user to create tables in the database warehouse they are
connected to via GeoMedia. This is useful for personal database but you should not use Feature Class
Definition to create tables in production databases and in many cases, the DBA does not grant the
privileges to do this to the connected users anyway. Since GeoMedia requires tables to be owned by
DBO, only a user in the database role dbowner should create tables using this method.

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

i. Select Ok to create the Feature Class.


11. Repeat the process to create a Linear feature class using the following information:
a. Name: LinearFeatures
b. Geometry type: Line
c. Attributes: LineID (autonumber Key column), CreateDate (Date), LineName (Text 30)
12. Repeat the process to create an Area feature class using the following information:
a. Name: AreaFeatures
b. Geometry type: Area
c. Attributes: AreaID (autonumber Key column), CreateDate (Date), AreaName (Text 50)
13. Repeat the process to create a Text feature class using the following information:
a. Name: TextFeatures
b. Geometry type: Text
c. Attributes: AreaID (autonumber Key column), StoredText (Text 50), XLoc (Double), YLoc
(Double)
14. When complete, the Feature Class Definition Dialog should resemble the one shown below:

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.

Basic Editing and Maintenance Triggers


Using the feature classes created in the previous section, digitize some simple data in GeoMedia and
then examine that data in SQL Server's Management Studio. This will give you are general idea of what's
going on behind the scenes when using SQL Server spatial data with GeoMedia.

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:

c. Place a point within the state boundary in the Map Window.


d. The PointFeatures Properties dialog will appear. Enter Point45 in the PointName field and
select OK.
e. Add two more points using 30 deg and 60 deg, naming them Point30 and Point60
respectively.
2. Change the feature class to LinearFeatures and digitize a line feature using point by point.
a. Double Click to end the line after placing several segments and then select OK on the
LinearFeatures Properties dialog.
b. Set the editing option to Arc by Center, place a center point within the state boundary, and
place an arc (number of segments does not matter, but have at least one, remember double
click to stop editing). Enter Arc for the LineName and select OK.
3. Change the feature class to AreaFeatures and digitize a polygon using the point by point option.
4. Digitize a second polygon using the Place by circle option (by center point) and enter Circle for the
AreaName.
5. Select the Insert Text button on the editing toolbar.
a. From the drop down list on the left, expand the GeoMedia Native Spatial connection and
select TextFeatures.
b. Place using Center and enter MyText in the large center field on the text placement toolbar
and then place the text within the state boundary.
c. On the TextFeatures Properties dialog, enter MyText in the StoredText field and then select
OK.
d. Place another text feature called MyText2 and this time, set the place at angle option to 45.
Also enter MyText2 in the StoredText field on the properties dialog and then select Ok.
e. Press the Esc key to stop the editing process. You should have something similar to what
you see below:

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;

Then query on the result:

Page 37
Working with SQL Server Spatial
Lessons

SELECT PointID, Geometry as GM_GEOM, Geometry_SPA.AsTextZM() as Native_Geom


FROM PointFeatures;

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.

Be careful when editing point geometries outside GeoMedia if point orientation is


important.
10. Prior to SQL Server 2012, arcs were not supported, so GeoMedia uses a similar method to support
true arcs and strokes the arc that are stored in the native geometry column.
a. In the SQL Server Management Studio, execute the following:
SELECT LineID, LineName, Geometry as GM_GEOM,
Geometry_SPA.AsTextZM() as Native_Geom
FROM LinearFeatures;

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;

The Native_Geom stores the text justification point


everything else is stored in the GDO geometry. If you edit a
text based feature class outside of GeoMedia, you will lose
the text!
12. If you disable the maintenance triggers, the GDO geometry
will remain intact but will be mismatched with the native
geometry and this could cause unpredictable results. As
SQL Server matures and stores more types, there will be less reliance on the secondary geometry
storage.

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.

1. Switch back to GeoMedia.


2. Select Warehouse>Export to> Sql Server…

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:

CMD> import SQLWorkshop Geomedia "" ""

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:

Output to Feature Class


Output to Feature Classes has not changed and works the same way as it does for any other data
server. The main thing to pay attention to with OTFC is how the key column is handled and making sure
the correct coordinate system is used. Also, keep in mind that OTFC is using the defaults set in the
GParameters table.

1. In GeoMedia, select Warehouse>Output to Feature Classes.


2. On the General tab, expand the AlabamaSampleData connection and check the box next to
Antennas and Railroads.
3. Set the Target Connection to GeoMedia Native Spatial and check the Display target feature classes
in map window option. Normally, you should not do this as it will affect performance but in this
case we do not need to worry about that.

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:

EXEC sp_help_spatial_geometry_histogram Roads_Primary, GDO_Geometry_SPA,


32, 360678, 3340758,698922, 3874594

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:

Zooming in and adding the IntersectionCount as the Label, you get:

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

This is the end of Lesson 3.

Page 45
Working with SQL Server Spatial
Lessons

LESSON 4: CONVERTING EXISTING DATA


In this Lesson, you will convert the dataset you used in Lessons 1-3 so that it will be visible inside
GeoMedia. This will demonstrate how to take an existing native spatial schema and make it
compatible with GeoMedia.

Goals

 Adding required columns


 Creating and updating metadata
 Creating Maintenance Triggers
 Spatial Filters
 Other GeoMedia Operations

Adding Required Columns


In order to make existing spatial tables work with GeoMedia applications, you need to add a
varbinary(max) column to store unsupported geometry types. Even if GeoMedia does not use the
column, it is required for GeoMedia to be able to connect to the spatial data.

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:

Alter table Denmark add Geometry_GDO varbinary(MAX);


Alter table Lakes add Geometry_GDO varbinary(MAX);
Page 46
Working with SQL Server Spatial
Lessons

Alter table NaturalAreas add Geometry_GDO varbinary(MAX);


Alter table Railways add Geometry_GDO varbinary(MAX);
Alter table RoadPts add Geometry_GDO varbinary(MAX);
Alter table Roads add Geometry_GDO varbinary(MAX);
Alter table UrbanAreas add Geometry_GDO varbinary(MAX);
Alter table UtilityLines add Geometry_GDO varbinary(MAX);
Alter table Waterways add Geometry_GDO varbinary(MAX);
Alter table EuropeWGS add Geography_GDO varbinary(MAX);
Alter table RailroadsWGS add Geometry_GDO varbinary(MAX);

5. Remember to select the Execute button!

Creating and Updating Metadata


Adding the required column is just the first step. GeoMedia requires metadata in order to connect so in
this section, you will add the required metadata tables, configure the metadata entries, assign
coordinate systems, and set the default parameters to use for the schema.

1. Use Database Utilities and connect to your Denmark database:


a. Database Utilities is under the Start Menu>GeoMedia Professional>Utilities
b. Set the Database type to SQL Server Spatial
c. Set the server to SQLWorkshop
d. Enter Denmark for the database name.
2. Select the Create Metadata Tables button to create GeoMedia's metadata table structure.
3. Since the majority of data in this database is projected, we will assign a projected coordinate system
as the default. To do this, select the Assign Coordinate System button.
a. On the Coordinate Systems dialog, select the New button.
b. On the Coordinate System Properties dialog, select the Load button.
c. Navigate to the C:\SQLWorkshop\Data directory and select EPSG25832.csf from the list of
coordinate files then select Open.
d. Enter Denmark - EPSG25832 in the Name field and optionally enter a description (if it's not
already set).
e. Select OK when complete and you should be back at the Coordinate Systems dialog with
Denmark - EPSG25832 highlighted. Select the Set As
Default button to make this the default coordinate
system for the database. Where is this information
stored?
f. When the default has been set, select Close.
4. When inserting feature class metadata, you need to ensure that
every feature class you select is in the same coordinate system. If
you make a mistake here you can always fix the problem using
Assign Coordinate System later. Select the Insert Feature Class Metadata button:
a. From the list of avaiLessonle tables/views, select Airports, Denmark, Roads and UrbanAreas
then use the > button to add them to the list on the right:

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

g. Select OK when complete.


5. Repeat the process for Denmark, Roads, and UrbanAreas, using the following information:
a. For Denmark, set the primary key to Autonumber (notice no error this time). On the
Geometry tab, set the Geometry Type to SpatialArea and assign both the Native geometry
column and the SRID.
b. For Roads, set the primary key to Autonumber and set the Geometry Type to SpatialLine and
assign both the Native geometry column and the SRID.
c. For UrbanAreas, set the primary key to Autonumber and set the Geometry Type to
SpatialArea and assign both the Native geometry column and the SRID.
6. When all three feature class have had their metadata set, select OK on the Insert Feature Class
Metadata dialog and assign the default coordinate system when prompted.

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

Creating Maintenance Triggers


Maintenance triggers are not required but they are a good idea. If you do not have maintenance
triggers, editing data outside of GeoMedia can cause a mismatch between what's stored in GeoMedia's
GDO column and the native geometry column. This could have serious consequences when displaying
the data inside GeoMedia. If editing will never occur outside of GeoMedia, then the trigger creation can
be skipped. I would NOT recommend this though, there is always a chance an outside edit is needed.

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.

1. Insert maintenance trigger for Airports:


CREATE TRIGGER [dbo].[Airports_ins] ON [dbo].[Airports] AFTER INSERT AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM INSERTED WHERE INSERTED.[Geometry] IS NULL
AND INSERTED.[Geometry_gdo] IS NOT NULL)
BEGIN
RAISERROR ('Unsupported operation on GDO column.', 0, 1);
ROLLBACK TRANSACTION;
END;
END;
GO

2. Update maintenance trigger for Airports:


CREATE TRIGGER [dbo].[Airports_upd] ON [dbo].[Airports] AFTER UPDATE AS
BEGIN
SET NOCOUNT ON;
IF UPDATE([Geometry])
BEGIN
IF NOT UPDATE([Geometry_gdo])
BEGIN
UPDATE [Airports] SET [Geometry_gdo] = NULL
WHERE EXISTS (SELECT NULL
FROM INSERTED WHERE INSERTED.[ID] = [Airports].[ID]);
END;
END;
ELSE IF UPDATE([Geometry_gdo])
BEGIN
RAISERROR ('Unsupported operation on GDO column.', 0, 1);
ROLLBACK TRANSACTION;
END;
END
GO

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.

1. Open GeoMedia and create a new workspace.


2. Select Warehouse>New Connection and create a SQL Server Native spatial connection to your
Denmark database. Name the connection DenmarkSpatial.
3. Select Warehouse>Spatial Filter Reference Features:
a. On the Spatial Filter Reference Features dialog, select Denmark as your reference feature
class:

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

7. The spatial filter toolbar commands are shown below:

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:

1. Select Analysis>Functional Attributes from the menu.


2. On the Functional Attributes dialog, add a Functional Attribute for: Denmark.
a. Select the New button to create a new Functional Attribute:
Page 56
Working with SQL Server Spatial
Lessons

b. From the Categories list, select Geometry.


c. From the Functions list, double click on
EXTERIOR (it will be added to the Expression
list).
d. From the Attributes list, double click on the
Input.Geometry_GDO.
e. Change the Functional attribute name to
ExteriorGeometry.
f. Select the Add button to add the attribute
and then select Close.
3. Change the Query name to Exterior Geometry for
Denmark.
4. Uncheck the data window display and then select OK to add the query to the legend.
5. Remove the spatial filter and then fit the legend entry for Denmark.
6. Double Click on the Exterior Geometry for Denmark legend symbol and then check the fill button on
the Legend entry Properties dialog. Select Ok when done.
7. On the legend, select the Exterior Geometry for Denmark legend symbol and drag it to the bottom of
the legend.

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.

This is the end of Lesson 4.

Page 59
Working with SQL Server Spatial
Lessons

LESSON 5: VIEWS, LOGGING, AND UTILITIES


This final formal Lesson is a catchall for remaining topics. It includes working with views, when to
control modification logging via triggers, and introduces you to GMPSpatialUtilities, a collection of
stored procedures that can be used for many of the tasks discussed in this workshop.

Goals

 Working With Views


 GMPSpatialUtilities
 Modification Logging

Working with Views


GeoMedia does not care whether the feature class is a table or a view; it makes the same assumptions
either way. GeoMedia does require a key column in order to have read-write access to a feature class.
Because views do not have key columns, they have to be key preserved in order for GeoMedia to be
able to utilize them. A key preserved column for a view can be any column in the view definition that is
both unique and not null. For views that contain spatial data, the key column must be the same as the
key used in the table containing the geometry. If this is not the case, the view will still work, but the
spatial index will not be used and spatial analysis will be slow.

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.

Here are some examples of working with views:

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?

Views and GeoMedia's Metadata


The key column to use for the view can be assigned via Database Utilities and the information is stored
in the GindexColumns metadata table. GeoMedia will first look here and then try to determine if the
view is key preserved. If neither case is true, the view will be read into GeoMedia as a Read-Only
snapshot. This means the entire contents of the view will be read into client side memory. This is not a
Page 61
Working with SQL Server Spatial
Lessons

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):

8. Select OK when all parameters are set


9. Now Select RailwayBuffer and then select Properties.
10. On the Attributes tab, set PID to the key column for the view.
11. On the Geometry tab, set the Geometry Type to SpatialArea, set the Native Geometry to
GeomBuffer and the Native SRID to Projected (SRID 0).
12. Select OK when all parameters are set.
13. Select OK on the Insert Feature Class Metadata dialog to Assign the default coordinate system.

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

b. To verify this setting, check the GParameters table:


SELECT * FROM GParameters;

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

EXECUTE GMPCreateGeometryGrid Denmark_Grid, 441704,6050158,892874,6401849,10,10

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:

EXECUTE GMPSetSRIDOn CitiesWGS, 4326


Page 64
Working with SQL Server Spatial
Lessons

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:

EXECUTE GMPSetMetadataFor Lakes


EXECUTE GMPSetMetadataFor NaturalAreas
EXECUTE GMPSetMetadataFor Railways
EXECUTE GMPSetMetadataFor RoadPts
EXECUTE GMPSetMetadataFor Waterways

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:

select name, csguid from gcoordsystem;

Page 65
Working with SQL Server Spatial
Lessons

And use the resulting CSGUID for Geographic (yours may be different):

EXECUTE dbo.GMPSetMetadataFor 'CitiesWGS', NULL,


'EA8B0E22-7948-4A31-97F2-E48CEC7FC071', 4326
EXECUTE dbo.GMPSetMetadataFor 'RailRoadsWGS', NULL,
'EA8B0E22-7948-4A31-97F2-E48CEC7FC071', 4326

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

For example, list the metadata for the table Denmark:

EXECUTE GMPListMetadataFor Denmark

--------------------------------------------------------------------------------------
-- 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:
--------------------------------------------------------------------------------------

And then try the view Sonderberg:

EXECUTE GMPListMetadataFor Sonderberg

--------------------------------------------------------------------------------------
-- 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
------------------------------------------------------------------------------------

Notice the additional entry in GindexColumns for the view.

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.

This becomes very apparent in the following scenario:

1. Create a view called Rivers using the following:


CREATE VIEW Rivers AS
SELECT WaterwayID, type as RiverType, Geometry, Geometry_GDO
FROM waterways where type='river';

2. Create the metadata for the view using the following:


EXECUTE GMPSetMetadataFor Rivers, NULL, NULL, NULL, WaterwayID

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?

9. For the deleted trigger, use the following:


CREATE 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
END;
GO

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

INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)


SELECT 1, convert(nvarchar(20),@TableID),
convert(nvarchar(255), inserted.[WaterwayID])
FROM inserted;
-- Added For View
SELECT @TableID=id FROM SYSOBJECTS WHERE name='Rivers'
INSERT INTO ModificationLog([Type], [ModifiedTableID], KeyValue1)
SELECT 1, convert(nvarchar(20),@TableID),
convert(nvarchar(255), inserted.[WaterwayID])
FROM inserted;
END;
GO
To complete this process, you also need to add a new insert trigger to handle the view itself. The
trigger is named for the view but operates on the base table and actually does nothing. It is just
there for GeoMedia book keeping. Execute the following:
CREATE TRIGGER dbo.RiversGMTI ON dbo.Waterways FOR INSERT AS
DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=1
END;
GO

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

And then add:

CREATE TRIGGER dbo.RiversGMTU ON dbo.Waterways FOR UPDATE AS


Page 72
Working with SQL Server Spatial
Lessons

DECLARE @TableID INT


if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=1
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

And then add:

CREATE TRIGGER dbo.RiversGMTD ON dbo.Waterways FOR DELETE AS


DECLARE @TableID INT
if object_id('tempdb..#DisableModificationLog') is null
BEGIN
SELECT @TableID=1
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.

This is the end of Lesson 5.

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

Phone: 770 / 776-3651


Fax: 770 / 776-3694

Support Services: 800 / 953-6643


Customer Education: 800 / 373-2713
Web: www.hexagongeospatial.com

Page 75

You might also like