Friday, August 15, 2008

Display Line Direction in GeoMedia

If you want to display the direction of line indicators in GeoMedia, there is an easy way using the Functional Attributes command. For example, I have the red line features in the screen shot below for which I want to display red arrows at the end to indicate the digitized line direction.



  1. In GeoMedia, select Analysis > Functional Attributes.

    The Functional Attributes dialog is displayed.


  2. Click New.

    The Functional Attribute dialog appears.

  3. In the Functional attribute name field, type in a meaningful name, e.g. LineDirection.
  4. In the Expression field, type in: ENDPOINT(Input.Geometry).

    The Functional Attribute dialog box should like this.


  5. Click Add.
  6. Click OK to close the Functional Attribute dialog.
  7. In the Functional Attributes dialog's Query name field, type in a meaningful name e.g. LineDirection.
  8. Click the Style button.

    The Select Style dialog appears.

  9. Click Properties.

    The Style Properties dialog appears.

  10. Under the Symbol Style tab, select the Triangle Up Filled Name.
  11. Choose a reasonable size e.g. 10pt.
  12. In the Rotation field, type in -90.
  13. Toggle on the Ignore map rotation option.

    The Style Properties dialog box should like this.


  14. Click OK to close all the dialog boxes.

    All the red line features should have a red color filled triangles at the end and pointing in the digitized direction.

Wednesday, August 13, 2008

Place Microstation Cells in FME

If you want to place Microstation cells from a cell library using the FME Workbench, the following must be done:
  1. In the destination dataset feature type, open up the Feature Type Properties form and enable the igds_type and igds_cell_name Format Attributes property.



  2. Right click on the igds_type property's green arrow and choose to Attach Constant to it. Then key in igds_cell as the constant value. Right click on the igds_cell_name property's green arrow and choose to Attach Constant to it. Key in the cell name e.g. TREE.



  3. Lastly, assign your cell library file to the destination dataset's Cell Library File parameter.



    Note: Make sure that the cell you are placing has a definition in the cell library.

Tuesday, August 12, 2008

Batch Geometry Snapping

During a GIS project some time ago, I had to snap the vertices of geometry features to reference or anchor geometry features. As the name suggests, the anchor geometries are geometries which could not be moved. For example, see the figure below: it shows an overlay of two geometry features. The blue line work is the candidate geometry (land use polygon) that is to be snapped to the anchor (reference) geometry in grey (land parcels).


As there were hundreds of thousands of geometries to be processed, doing it interactively was out of the question and the job had to be done in batch mode. I did some research and learnt about the Anchored Snapper factory in SAFE FME Professional. Here I describe how to perform snapping of geometries using the Anchored Snapper.
  1. Open up the FME Workbench and define the source dataset for the candidate geometries for snapping (e.g. land use) and the anchor geometries (e.g. land parcels).
  2. Add in the Anchored Snapper factory and define the following parameters.



    Note: Enter a suitable snapping tolerance for your dataset.

  3. Define the destination datasets.

    I defined destination datasets for the snapped geometries, the untouched geometries, and the combined snapped and untouched geometries.

  4. Connect up all the datasets and the factory as shown in the figure below.



  5. Run the conversion.

    The results of the snapping are shown below. The red linework is the new snapped geometry while the light blue linework is the unsnapped geometry.

The SAFE FME algorithm was pretty efficient and the snapping process for a couple of hundred thousand polygon geometries took a short time (as in less than half an hour) to process. So I had the luxury of doing multiple runs with different tolerance values.

Wednesday, August 6, 2008

GeoMedia Datum Transformation from Kertau to WGS84

GeoMedia automatically performs datum transformation between two different coordinate system. The parameter file that controls this automated transformation is autodt.ini, which can be found in the folder drive:\Program Files\GeoMedia\Program\cssruntm\cfg\. For Singapore and West Malaysia, the default transformation from Kertau 1948 to WGS84 uses the Standard Molodensky transformation. If you open up the autodt.ini file with a text editor and search for the line with the string 'csgdKertau', you can find the following line:


; Kertau 1948 (West Malaysia and Singapore)
csgdKertau1948,csvdUserDefined,csgdWGS84,csvdUserDefined,csdtStandardMolodensky,-11,851,5


On some occasions, you may not want to use the Standard Molodensky transformation. Instead, a Second Degree General Polynomial transformation or Affine transformation that stretches may be more suitable, e.g. the SVY21 global transformation. To change GeoMedia to use the 2nd Degree General Polynomial, the above line in the autodt.ini file needs to be commented out and replaced with the following:


; Kertau 1948 (West Malaysia and Singapore)
csgdKertau1948,csvdUserDefined,csgdWGS84,csvdUserDefined,csdt2ndDegGeneralPolynomial,igDistanceMeter,igDistanceMeter,0,0,1,1,2.726683,0.999970,-0.000059,0,0,0,-0.130398,0.000058,0.999955,0,0,0


The numbers are simply the constants in the Affine transformation formula. Replace these numbers with your own constants. Below is an example.
East(WGS84) = a1 * East(Kertau) + b1 * North(Kertau) + c1
North(WGS84) = a2 * East(Kertau) + b2 * North(Kertau) + c2

a1 = 0.99970
b1 = -0.00005
c1 = 2.72668
a2 = 0.000058
b2 = 0.99955
c2 = -0.130398

Note: All future automatic datum transformation between Kertau 1948 and WGS84 will use the 2nd Degree General Polynomial algorithm with the constants you have defined.

Thursday, July 24, 2008

Terrain in GeoMedia WebMap Mashup

In addition to the Satellite, street map, and hybrid map types, Google Maps also publishes a terrain map type. If you use the default GeoMedia WebMap 6.1 Publisher template to create a new Google Maps mashup, you will notice that there is no terrain button in the web page; only the Map, Satellite, Hybrid, and No Backdrop buttons are available. See the screen shot below.

To enable the display of terrain shaded relief data from Google, you need to add in the terrain map type to the Google Maps javascript code. Here are the steps to do it.
  1. Go to the GeoMedia WebMap Publisher created mashup folder, e.g. C:\GeoMediaWebMapProjects\mymashup\
  2. Change directory to the System folder.
  3. Use a text editor to open the file gm.js.
  4. Inside the text editor, locate the function initView.
  5. Look for the following lines in the function.



    objMapViewEle = document.getElementById("map");
    //testoutput("creating new custom map type");
    var tileLayers = [new GTileLayer(new GCopyrightCollection(), 0, 18)];

    var custommap = new GMapType(tileLayers, G_NORMAL_MAP.getProjection(), "No Backdrop",{errorMessage:"No Data Available"});
    //testoutput("creating GMap2");
    objMapView = new GMap2(objMapViewEle);

    objMapView.addControl(new GLargeMapControl());

    objMapView.addMapType(custommap);

    objMapView.addControl(new GMapTypeControl());

    gOverviewMapControl = new GOverviewMapControl(new GSize(150,150));
    objMapView.addControl(gOverviewMapControl);
    objMapView.addControl(new GScaleControl());


  6. Add in the following line in bold:

    objMapView.addMapType(custommap); objMapView.addMapType(G_PHYSICAL_MAP); objMapView.addControl(new GMapTypeControl());

  7. Save and close the file gm.js.
  8. Now, open up the mashup web page in an Internet browser. You should be able to see the Terrain button. Clicking on the button will display the terrain data in the map window as shown in the screen shot below.



There you go. Just remember, that the change in gm.js will be overwritten if you decide to republish the mashup again from GeoMedia WebMap Publisher.

Thursday, July 10, 2008

Query Oracle Spatial in Microsoft Excel

Oracle has been building spatial query tools inside the database engine for many years now since Oracle 8i. But I have not seen many examples of Microsoft Office applications that directly query a Oracle Spatial database for spatially related information without having to use any GIS vendors' software.

A simple example that came to my mind is an Office application that generates water usage demand reports by geographic regions. Here, I outline the steps I took to create a simple Excel VBA to query an Oracle Spatial database. The VBA will look for all point geometries INSIDE a polygon geometry to calculate the total demand by usage type and the results printed to an Excel sheet.

Create Sample Oracle Data
For my convenience, I used Intergraph's GeoMedia Professional 6.1 to create a couple of Oracle tables CUSTDATA and DEMANDPOLYGON with GEOMETRY fields. However, you can use any tool of your choice to create the spatial tables. Even plain SQL statements through the Oracle SQL*PLUS prompt is fine.

CREATE TABLE CUSTDATA
(
ID INTEGER,
POSTCODE VARCHAR2(6),
BPNAME VARCHAR2(255),
TELNO VARCHAR2(10),
ACCTCLASS VARCHAR2(255),
PREMISENUM VARCHAR2(50),
PREMISEADDR VARCHAR2(255),
AVGBILL FLOAT(126),
X FLOAT(126),
Y FLOAT(126),
GEOMETRY SDO_GEOMETRY
);

CREATE TABLE DEMANDPOLYGON
(
ID INTEGER,
DESCRIPTION VARCHAR2(255),
GEOMETRY SDO_GEOMETRY
);

CUSTDATA holds point geometry data while DEMANDPOLYGON stores polygon geometries. After creating the tables, I inserted a few records inside the newly created tables. My sample data looks like the screen shot below.



Create an ODBC Data Source
If you don't have an ODBC Data Source Name pointing to the Oracle schema, then you can use the Control Panel's ODBC Data Source Administrator to define one as shown in the two figures below.




Create a New VBA in Microsoft Excel
  1. Bring up Microsoft Excel and create a new Excel Workbook. Then click Tools > Macros > Visual Basic Editor to bring up the VBA Editor.



  2. Select Tools > References. Select Microsoft ActiveX Data Objects 2.1 library to reference.



  3. Select Insert > UserForm to create a new form. By default, it is named as UserForm1.
  4. Using the IDE's toolbox, add in the following controls: Label, ComboBox, and 2 CommandButtons. Arrange the controls as shown in the figure below. Name the CommandButton controls as cmdOK and cmdCancel.



  5. Select View > Code to enter the VBA code for the UserForm1. Enter the following code.

    Option Explicit

    Dim mobjConnection As ADODB.Connection

    Private Sub cmdOK_Click()
    Dim sql As String
    Dim objRs As ADODB.Recordset
    Dim demandType As String
    Dim demand As Double
    Dim excelRow As Integer

    'Form the Oracle Spatial query statement
    sql = "SELECT A.ACCTCLASS,SUM(A.AVGBILL) AS DEMAND FROM CUSTDATA A, DEMANDPOLYGON B "
    sql = sql & "WHERE "
    sql = sql & "B.DESCRIPTION='" & ComboBox1.Text & "' "
    sql = sql & "AND "
    sql = sql & "SDO_RELATE(A.GEOMETRY,B.GEOMETRY,'MASK=INSIDE')='TRUE' "
    sql = sql & "GROUP BY A.ACCTCLASS "
    sql = sql & "ORDER BY A.ACCTCLASS ASC "

    'Print out the report title and heading on the Excel sheet
    With Sheet1
    .Range("A1").Value = "REPORT OF WATER DEMAND FOR " & ComboBox1.Text
    .Range("A2").Value = "TYPE"
    .Range("B2").Value = "TOTAL DEMAND"
    End With

    'Submit the query to Oracle and loop through the recordset.
    'Print out the results in the Excel sheet
    excelRow = 3
    Set objRs = New ADODB.Recordset
    objRs.Open sql, mobjConnection
    While Not objRs.EOF
    demandType = objRs.Fields(0)
    demand = objRs.Fields(1)
    Sheet1.Range("A" & excelRow).Value = demandType
    Sheet1.Range("B" & excelRow).Value = demand
    excelRow = excelRow + 1
    objRs.MoveNext
    Wend
    End Sub

    Private Sub UserForm_Initialize()
    Dim username As String
    Dim password As String
    Dim dataSourceName As String
    Dim connString As String

    username = "demo"
    password = "demo"
    dataSourceName = "demo"

    ' Open a ADO database connection to the Oracle Spatial Schema
    connString = "Data Source=" & dataSourceName & ";User ID=" & username & ";Password=" & password & ";"
    Set mobjConnection = New ADODB.Connection
    With mobjConnection
    .ConnectionString = connString
    .ConnectionTimeout = 10
    .CursorLocation = adUseClient
    .Open
    End With

    'Query the DEMANDPOLYGON table for the names of all the polygons
    'Add the names to the combo box for selection
    Dim sql As String
    Dim objRs As ADODB.Recordset
    sql = "SELECT DISTINCT DESCRIPTION FROM DEMANDPOLYGON ORDER BY DESCRIPTION ASC"
    Set objRs = New ADODB.Recordset
    objRs.Open sql, mobjConnection
    ComboBox1.Clear
    While Not objRs.EOF
    ComboBox1.AddItem objRs.Fields(0)
    objRs.MoveNext
    Wend
    ComboBox1.ListIndex = 0
    objRs.Close
    Set objRs = Nothing

    End Sub

  6. In the VBA IDE' project pane, right click on the ThisWorkbook object and select View Code. Add in the following code.

    Private Sub Workbook_Open()
    UserForm1.Show
    End Sub

  7. Now save and close everything.

Running the Excel VBA
Double click the Excel file you created previously. The Excel Workbook should open and you would be prompted with the following:



Choose a region from the drop down list and press OK. The Excel VBA would submit a spatial query to Oracle to find all the CUSTDATA records inside the selected demand polygon. The results are grouped, tabulated and displayed in the Excel spreadsheet as shown below.



Notes
The example code shown is quite unsophisticated. I have hardcoded the Oracle login, password and ODBC data source name. There is also no error handling at all. These are intentional as the example is just meant to illustrate a technique.

Wednesday, July 2, 2008

GeoMedia WebMap Publisher 6.1 Permission Denied Error

This must be a beginner's mistake but it stumped me for a couple of days. On a Windows XP SP2 notebook, I tried to run GeoMedia WebMap Publisher 6.1's Server Configuration Utility - but I kept getting a permission denied error message as shown below.

I suspected the DCOM Config Access Permissions may not be granted with the correct permissions but I could not see it. I thought I had set all permissions as per according to the Web Map Publisher instructions. But then some kind soul from the GeoMedia Developer's forum pointed to me that the INTERACTIVE user needs to be granted access permission also in the Component Services.


Once I did that, I had no problems bringing up the Publisher Server Configuration Utility.