You are on page 1of 229

Introduction ...................................................................................................................................... 3 Automation Overview ...................................................................................................................... 5 Object-Oriented Programming and OLE.................................................................................... 7 What is COM?............................................................................................................................ 9 Benefits of OLE .......................................................................................................................

10 What is Automation?................................................................................................................ 11 Manipulating Objects ............................................................................................................... 13 Terminology ............................................................................................................................. 16 Driving Excel Automation ....................................................................................................... 19 GeoMedias Automation Capabilities...................................................................................... 22 Approaches to Customization .................................................................................................. 44 Summary................................................................................................................................... 50 Can You Answer These Questions?......................................................................................... 51 Creating a Custom Application .................................................................................................... 53 Connecting to the GDO Server ................................................................................................ 55 Creating and Manipulating Recordsets .................................................................................... 62 Adding a MapView and Displaying Data ................................................................................ 69 What are Styles?....................................................................................................................... 75 What is Marginalia? ................................................................................................................. 80 Printing Maps ........................................................................................................................... 83 Creating and Displaying Queries ............................................................................................. 86 Spatial Query Pipe.................................................................................................................... 88 Buffer Zone Pipe ...................................................................................................................... 96 Locating Features ................................................................................................................... 100 Creating a Data View ............................................................................................................. 105 Custom Application Limitations ............................................................................................ 113 Summary................................................................................................................................. 117 Can You Answer These Questions?....................................................................................... 118 Adding Commands to GeoMedia................................................................................................ 119 GeoMedias Command Wizard.............................................................................................. 121

2 Fundamentals of GeoMedia Development Part I

Command Types..................................................................................................................... 127 Creating the Command Skeleton............................................................................................ 131 Modal Commands .................................................................................................................. 142 Modeless Commands ............................................................................................................. 154 Summary................................................................................................................................. 169 Can You Answer These Questions?....................................................................................... 171 Appendices .................................................................................................................................... 173 Document Conventions .......................................................................................................... 173 Reference Materials ............................................................................................................... 174 Where to Get Help.................................................................................................................. 175 Lab Exercises ......................................................................................................................... 176 Feature List for Lab 14........................................................................................................... 177 Visual Basic Syntactical Constructs....................................................................................... 181 Visual Basic Notation Conventions ....................................................................................... 186 PowerBuilder Syntactical Differences ................................................................................... 192 Delphi and GeoMedia ............................................................................................................ 194 Automation Overview Diagrams............................................................................................ 195 OriginatingPipe GRecordset vs. GDO GRecordset ............................................................... 196 Programming Caveats ............................................................................................................ 197 Feature Selection Controls ..................................................................................................... 199 Raster Formats........................................................................................................................ 201 GetExtension Method............................................................................................................. 202 ExtendedPropertySet.GetValue Method ................................................................................ 204 Common Interfaces ................................................................................................................ 207 Type Libraries and Objects .................................................................................................... 208 Object Bundles ....................................................................................................................... 216 Collections: Indexing and Object Types ............................................................................... 222 Instructors Overheads ........................................................................................................... 229

Introduction3

Introduction
Welcome to GeoMedia and the Team GeoMedia development workshop!

GeoMedia
GeoMedia is a universal geographic client that augments standard Intergraph products like MGE and FRAMME as well as providing access to geographic data in non-Intergraph formats. GeoMedia provides the ability to access multiple geographic data sources simultaneously for display, analysis, and presentation. These capabilities allow professionals of all industries to communicate geographically. The three fundamental principles of GeoMedia are: Data integration and access GeoMedia lets the user integrate geographic data from multiple vendors and standard data sources. The user can perform analysis against multiple data sources without costly translations between formats. Productivity By extending Windows standards through Intergraphs Jupiter technology, GeoMedia defines new ways of thinking spatially, performing analysis, and communicating geographically. Customization Through OLE Automation, GeoMedia is directly accessible through automation clients like Visual Basic. This allows you to either customize or extend the GeoMedia product or to build your own application with GeoMedia components.

Team GeoMedia
Team GeoMedia is a membership program for developers of GeoMediabased applications as well as for anyone who uses the GeoMedia objects or product for development, consulting, systems integration, or data provision. Team GeoMedia is designed to develop relationships with leading independent software vendors, consultants, systems integrators, industry advisors, and data producers around the world. By stressing the unique

4 Fundamentals of GeoMedia Development Part I

abilities of each partner, successful cooperative relationships will be formed. Ultimately, this means a better set of products to meet the expanding needs in the GIS industry. Team GeoMedia membership is also valuable to any MIS professional developing enhancements for intracompany use of GeoMedia. The program provides an avenue for distributing valuable technical information to all developers. If you are not currently a Team GeoMedia member, we encourage you to learn more about the program through the world wide web at http://www.ingr.com/geomedia/team_geo.htm. We look forward to a successful relationship.

Course Objectives
Over the next three days, the course will provide you with extensive information about the GeoMedia product, the automated objects, and custom development techniques. While the course will not be able to present every object and every possible manipulation of that object, it will cover the fundamental operation of most objects as well as the most common operations with those objects. The course is divided into three sections. Automation Overview Adding Commands to GeoMedia Creating a Custom Application

Each section builds upon the knowledge gained from the prior section. While the material provides you with some background information on automation and Visual Basic, the intention is NOT to teach you this material. Rather, the focus is on the effective use of GeoMedias objects. The workshop makes extensive use of hands-on lab exercises. The labs are presented in a format that provides hints in the skeleton code to guide you through the completion of the exercise. A solution set is also provided. All materials including the labs, course text, and presentation slides are included on the floppy disks in your course manual. While we have presented the material using Microsofts Visual Basic as the automation controller, the GeoMedia objects may be used with any robust automation controller. PowerBuilder, Delphi, and Visual C++ are very popular tools. We hope that you find the information presented here useful in your application development activities. Please complete the course evaluations provided in your binder so that we may better serve you in the future.

Automation Overview
Introduction
The term automation will be used frequently and in many different contexts. This section will introduce many of the terms used in automation programming. The automation model for GeoMedia will be analyzed and the mechanisms for customizing GeoMedia will be presented. The lab exercises will reinforce the OLE Automation concepts.

Topics
1. Object-oriented programming and OLE 2. What is COM? 3. Benefits of OLE 4. What is Automation? 5. Manipulating Objects 6. Terminology 7. Driving Excel Automation 8. GeoMedias Automation Capabilities 9. Approaches to Customization

Objectives
At the end of this section, you will be able to do the following: 1. Define common programming terms 2. Navigate the GeoMedia automation model 3. Describe the three techniques for customizing GeoMedia

Demonstrations
Introduction to GeoMedia Driving Excel through Automation

6 Fundamentals of GeoMedia Development Part I

Labs
Navigating the GeoMedia Automation Model

Automation Overview 7

Object-Oriented Programming and OLE


As we look at GeoMedia customization, the terms object and automation will be pervasive. The term object surfaced in conjunction with objectoriented programming techniques. While object-oriented paradigms have existed for many years, they are receiving considerable emphasis in todays software development environments. An object-oriented system focuses on an organization of software that encapsulates data structures and behavior into discrete components or objects. So, in GeoMedia, a software component that provides an encapsulated set of functionality is termed an object. Automation is the process of communicating with these software objects as part of creating applications. Before we look at how we use automation, we need to first review some history of the present day software architecture. Much of the broader focus on object-oriented programming started through the introduction of OLE. In its initial form, OLE meant Object Linking and Embedding. In this context, OLE enabled you to create objects (files, applications) and build relationships between them. For instance, you could include an Excel spreadsheet inside a Word document and double click on it to start Excel. OLE, in its current form, enables the following techniques. Integration of components (objects) Independence of language through a binary standard Abstraction of interfaces to components (objects)

More specifically, OLE includes three distinct elements: compound documents, automation, and OLE controls. A compound document is a document that contains, along with native data, one or more objects that were created in other applications. Additionally, it exhibits the behaviors of in-place activation and drag-and-drop. OLE Automation can be defined as one application exposing objects to be programmatically manipulated by another application. For example, Microsoft Excel can expose spreadsheet and chart objects that can be manipulated by a program written using Visual Basic. Or, Intergraphs GeoMedia can expose map views and pipes that can be manipulated by a program using Visual Basic or Visual C++. Finally, OLE controls embody many of the OLE technologies, including COM, connectable objects, compound documents, property pages, OLE Automation, and object persistence. A control or widget is a software component that is usually visible to the user a button, a listbox, a checkbox and is used to provide the building blocks for creating user interfaces in applications. A custom control is one built by a user to

8 Fundamentals of GeoMedia Development Part I

address a specific problem encountered in the workflow. Obviously, these topics require a much deeper analysis for you to become proficient in their effective use and development. However, by introducing these concepts, you can see where GeoMedia customization fits into the bigger picture of todays software architecture. Our primary focus for the workshop is the automation aspect of OLE technologies.

Automation Overview 9

What is COM?
Although not integral to our objectives for customizing GeoMedia, a brief summary of Microsofts Component Object Model (COM) is worthwhile. GeoMedias architecture is founded upon this model. Understanding the basic principles is useful even if you never create a programmable object. OLE is built upon COM. COM defines and implements mechanisms that enable software components (objects, controls, applications, and services) to interact. That is, COM defines a communications protocol for software components. COM describes manipulating interfaces, reporting status, and the use of the system registry to resolve universally unique identifiers. COM also defines the interaction of objects within or between applications. Interfaces are integral to the implementation of COM. A COM interface is a specification for interaction between COM objects. Consider the interface as a contract between a producer and consumer that defines the intent and behavior of the software. An interface is comprised of a list of semantically related functions (or methods) for the COM object. Once an interface is defined, it cannot change. That is, the contract cannot be broken. This contract protects you as an application developer from changes to the software you depend on in your application. The Component Object Model is the key to OLEs extensible architecture, providing the foundation on which the rest of OLE is built. COM is a binary standard for component communication. COM is not dependent on Windows NT. Microsoft and other vendors are implementing COM libraries on other platforms, including Unix and Macintosh. For more information on COM, visit the Microsoft Developer Network (start at http://www.microsoft.com/). The book Inside OLE 2 by Kraig Brockschmidt is a powerful source of information. Refer to the appendix for publishing information.

10 Fundamentals of GeoMedia Development Part I

Benefits of OLE
OLE provides great benefits to both users and developers. OLEs emphasis is on "document-centric" programming rather than applicationcentric programming. That is, the data and data format are independent of the application. Users can manipulate a document (data) with several applications without costly conversion processes. Data can also be shared across documents. By providing access to data without making a copy of the data, the information is better maintained and it simplifies the business operations for distribution of information. The use of OLE objects and interfaces provides developers with the tools they need to create flexible applications that can be easily maintained and enhanced. OLE applications can specialize in one area, taking advantage of features implemented in other OLE applications to increase their usability. This speaks to the adage of using the best tool for the job. As application developers, we no longer are faced with creating all of the needed functionality. We can utilize other OLE applications to meet our objectives. GeoMedia fits into this architecture as an embeddable technology. Although we have not discussed some of the architectural requirements of OLE and COM, we know that there is a protocol for communication between objects and automation clients or controllers. This protocol is an interface. All objects support this important interface (IUnknown). Through these interfaces, you can learn at runtime about the capabilities of other applications that relate to object services. Support for additional objects and interfaces can be added without affecting either the current application or those applications that interact with it. Remember, this is the contract of COM once an interface is defined, it cannot be changed. GeoMedia supports this through consistency in the programming contract.

Automation Overview 11

What is Automation?
OLE Automation is an industry standard that applications use to expose their OLE objects. There are two primary facets of automation: the controller and the object. An automation controller is the scripting tool that enables your program to communicate with the automation objects. Automation controllers include VC++, Visual Basic, PowerBuilder, Developer 2000, and Delphi. Automation objects are the programmable components that support the necessary OLE interfaces. Additionally, an entire application might be an automation object. For example, a spreadsheet application may expose a worksheet, chart, cell, or range of cells all as different types of objects. A word processor might expose objects such as application, document, paragraph, sentence, bookmark, or selection. Automation Controller: scripting tool used to create programs that manipulate automated objects. Same as automation client. When an application supports OLE Automation, the objects it exposes can be accessed by any automation controller (VB, VC++, etc.). You use the scripting tool to manipulate the applications objects by invoking methods on the object or by getting and setting the objects properties. Automation Object: programmable software component manipulated by automation controller. Same as automation server. You might find literature that refers to automation clients and servers. A client is equivalent to a controller. A client is a scripting tool or an application built with this tool that manipulates automation objects. A server is equivalent to an object. An automation server is a software component that can be manipulated by any automation client. It exposes programmable objects. Exposing programmable objects enables clients to automate certain procedures by directly accessing the objects and functionality the server makes available. Supporting automated objects allows you to fine-tune your workflow using existing applications. You can also create very specialized applications that utilize the power of other applications. This equates to less development time and less support for you, as well as meeting very specific needs for your organization. Through the standardization of the automation interface, this application can be built in a single general programming language instead of the multiple scripting languages

12 Fundamentals of GeoMedia Development Part I

associated with the various products. For an automation client to effectively access the automated objects, the client (controller) must have information about the servers objects. Within each object, you must have information about the properties and methods of the object. To achieve this information exchange, the server will create a type library which defines each object. The type library also describes the properties of the object including the data type of each property. Finally, the objects methods are described. The description includes the return values and the methods argument list variable and data type. In GeoMedia, we have one type library for each DLL and OCX, as well as one for the applications executable. The type library file has a .tlb extension. In the case of Visual Basic automation servers, the DLL itself contains the type information. The list of GeoMedia objects and their corresponding type libraries is presented in the Appendix.

Automation Overview 13

Manipulating Objects
In order to be effective in programming automation servers, you must understand how to manipulate the automated objects. We can collectively refer to the attributes of an object as the interface to the object. The first attribute type is the property. If we think of an object as a structure, a property is a member variable. Properties control the characteristics of objects like color and weight. A method is the operation associated with the object. In the object-oriented sense, methods embody the behavior of the object. Almost all objects will have both properties and methods. Some objects will also have the third type of attribute events. An event is a signal or action that an object responds to. For example, clicking on a radio button on a form will trigger a click event on the radio button object. Controls typically have events. A member object is a property of one object which is itself another object. For instance, the GeoMedia application object exposes a Document property. The Document property is also an object. The Document is then a member object of the application object. A dependent object is like a member object but it has a stricter relationship with the containing object. A dependent object cannot be created independently of the containing object. For example, the GField object in GDO is a dependent object on the GTableDef object. You must use a method on GTableDef to create a GField object. Finally, we need to discuss a special kind of object known as a collection. A collection is an automation object which groups or manages a set of similar objects. A collection object normally has the same name as the objects it manages simply distinguished by the plural form. For example, Windows is a collection of Window objects; Queries is a collection of Query objects. The objects within a collection may be homogeneous or heterogeneous in nature. The Windows collection is heterogeneous in that it contains DataViewWindow and MapViewWindow objects. The Queries collection is homogeneous in that it contains only Query objects. It is important to understand the type of collection you are manipulating as you often process all members of a collection. Collection: set of related objects Although a collection object can have its own unique methods and properties, it must have a Count property and an Item method. The Count property indicates the number of objects in the collection. The Item method supports the iteration process:

14 Fundamentals of GeoMedia Development Part I

For i = 1 To objCollection.Count objX = objCollection.Item(i) Next I The standard for new collections is to begin the iteration at one (1). This is often referred to as a base 1. However, you will find some collections begin iteration at zero (0). In GeoMedia, all GDO collections are base 0, while the GeoMedia collections are base 1. Additionally, collections often have these methods: Add values or Append object Remove index or Delete object _NewEnum hidden method that supports the For Each construct

Objects typically have a default method or property. This default mechanism allows you to omit the property or method name and implicitly retrieve the value or execute the method. For example, the Item method is usually the default for the collection object. In this situation, objCollection.Item(i) objCollection(i) are equivalent statements. In the text control, the Text property is the default. Then, txtControl1.Text txtControl1 have the same effect of retrieving the value in the text control. Table 0-1 Object Characteristics Attribute Property Method Event Member / Dependent Object Collection Description Data member or characteristic Procedure or function which operates on the object Action recognized by an object Constituent element of a collection or object An object which contains a set of similar objects

Another important concept in manipulating objects is the dot or navigational operator. This is syntactically represented by a period or dot

Automation Overview 15

(.) in Visual Basic. The dot operator provides access to the values of the properties of the object and initiates the methods on the objects. When an object contains member objects, you can use the dot operator to traverse the entire object hierarchy. Consider an Application object with a Document member object. The Document object has several properties including the Name. Through the use of the dot operator, we can retrieve the name of the Document with: Application.Document.Name There is no limit to the depth of the hierarchy that can be traversed. However, code readability will suffer and there is a potential performance penalty for repeated traversals. Since each dot initiates a request to the automation server, you should examine your use of this operator. For instance, if you are accessing several properties on an object or are processing an object within a loop, it is much more effective to either use a With block or introduce an intermediate or temporary variable as a placeholder. For instance: Application.Document.Name = Automation Overview Application.Document.Date = 7/12/97 Application.Document.Author = John Doe is more efficiently written either as: Set tmpDoc = Application.Document tmpDoc.Name = Automation Overview tmpDoc.Date = 7/12/97 tmpDoc.Author = John Doe or: With Application.Document .Name = Automation Overview .Date = 7/12/97 .Author = John Doe End With Both methods eliminate two navigation steps through Application.Document. Dot / Navigation Operator: mechanism for accessing property values or initiating methods of objects.

16 Fundamentals of GeoMedia Development Part I

Terminology
Dim, New, CreateObject
In each automation client (controller), as in any programming language, there must be some mechanism for declaring variables. In Visual Basic, this is accomplished with the Dim statement. The Dim statement is also used to declare object variables. For example, Dim objX As Object establishes objX as a pointer to any object. This occurs because Object is a generic term that does not indicate the exact type of the object. Since this is a pointer, you must set the value of the pointer to an object. One mechanism for accomplishing this is to set it to a member or dependent object property of another object: Dim objDoc As Object Set objDoc = Application.Document You may also create an object using the function provided by your automation controller where you have a reference to MyApplications type library in your project: Set objDoc = CreateObject(MyApplication.Document) In Visual Basic, you can also achieve the latter functionality with the New operator: Dim objDoc As New Document In both of the latter examples, you have actually created a new object. In the first example, you simply created a reference to (shared) an existing object. Not all objects are externally creatable. This rule implies that the New operator and the CreateObject function will fail when attempted. You can also create a variable that references an objects interface with the Dim statement. You cannot, however, create an instance of an interface object. We will see how interfaces surface in the GeoMedia model later in the workshop.

In-Process, Out-of-Process
There are two ways to communicate with an automation server: inprocess and out-of-process. An in-process server is created as a DLL, and the client is either a DLL or an EXE. An out-of-process server is created as an EXE, and the client is either a DLL or an EXE. The distinguishing difference between these two types of implementations is that an inprocess server shares the same address space as the client. Hence, it can

Automation Overview 17

be significantly faster than an out-of-process server. The out-of-process server has its own address space. To its advantage though, it can serve multiple clients simultaneously. The significance of these two types of servers will be important later when we look at how to create custom commands and write independent applications using GeoMedia.

UUID, GUID, CLSID, PROGID


You might wonder how an automation controller keeps track of objects that is, how does it uniquely identify them? All interfaces and automation objects are represented by a universally unique identifier (UUID). The value is also known as a globally unique identifier (GUID). A GUID is a 128-bit value that is generated by a program and is guaranteed to be unique globally. The value is generated based on time of day, the date, and a unique number contained in your network card. There are two specific types of GUIDs: interface identifiers (IID) and class identifiers (CLSID). Each interface is defined by its own interface identifier (IID). This value is used to find the correct interface (set of functions) associated with an object. Once you have the interface, you have access to the methods within the interface. Most automation controllers convert from object type names to interface identifiers automatically so you will not be exposed to this information directly. A class identifier is associated with each type of automated object. The class identifier is used in creating objects of the given type. As with IIDs, this GUID is used to uniquely define the objects (classes) supported by an automation server. Finally, each class has a programmatic identifier (ProgID). This is a string that uniquely identifies the object in the registry. An API exists for converting between the ProgID and the CLSID, and vice versa. Underscores and periods are the only allowable punctuation. The CLSID for most GeoMedia objects begin with GeoMedia. and is followed by the class name. The ProgID is the argument to CreateObject in your automation controller. For example, GeoMedia.Application, GeoMedia.Connection, and GeoMedia.ColorSchemes are ProgIDs. Access.GDatabase is the ProgID for the Access GDO server.

Interface
Interfaces are the mechanism by which you communicate with an object. An object may have one or more interface pointers. Recall that an interface is a set of related functions. Typically, the relationship between functions in an interface is one of purpose. For example, an object may

18 Fundamentals of GeoMedia Development Part I

have a persistence interface that provides the methods for saving and loading the object. Another interface might be the automation methods for the object. An interface is an abstract C++ class whose definition is stored in a type library. All member functions return an HRESULT a special type of error code which indicates success or failure of the member method. Remember that an interface defines a contract which must not change once defined. All automation objects will implement at least three interfaces: IUnknown, IDispatch, and an automation interface. Several objects can implement the same interface. Semantically, the member functions perform the same operations. However, they may implement that function differently as long as the semantic meaning has not changed. This diagram provides a visualization of an object and its interfaces. Most automated objects will have three interfaces some of which are acquired through inheritance. MyAutomatedClass IUnknown Interface AddRef Release QueryInterface IDispatch Interface Invoke GetIDsOfNames GetTypeInfoCount GetTypeInfo MyAutomatedClass Interface get_Value1 set_Value1 MyMethod1 MyMethod2

Automation Overview 19

Driving Excel Automation


This section shows an example of OLE automation outside of GeoMedia. The material is provided to emphasize that automation is a standard programming technique and not a proprietary approach. The remainder of the course material will not be affected by the omission of the section. Many applications today are automation servers. As such, you can write a program to access the objects they expose to use the capabilities of the application without interactively operating the application. Such a capability is extremely powerful to an application integrator. The best tools can be used for particular tasks, but the interface to the tools can be encapsulated in a small set of end user programs. Automated objects are not unique to Intergraph. Many applications from Microsoft and other vendors are automation servers. Automation is quickly becoming a common mechanism for extending the capabilities of an off the shelf application to better suit your needs. This section will use Excel to illustrate some of the automation concepts. Although there is no direct correlation between Excels automation and GeoMedias, spreadsheets can provide a common ground for introducing these automation concepts. As is the case with most automation servers, the root object of the hierarchy is the application object. Traversing an automation hierarchy is much like following the steps you would take interactively in using the application.

20 Fundamentals of GeoMedia Development Part I

This type of drawing is often used to express the automation model of an application. This automation diagram shows the objects and their hierarchical relationship to one another. Each box represents an automated object. Gray boxes are used to represent a collection object and the object it contains. In this example, Application contains (has a member object) of Workbooks. The Workbooks collection contains Workbook objects. Workbook object has members Worksheets, DialogSheets, Charts, and Modules. Worksheets collection contains Worksheet objects. Worksheet object has a member object, Range. Range contains Areas collection and Border member objects.

There are many other objects within the model for Excel. Each object can be further traversed until you reach an object which has no member or dependent objects. Each member or dependent object will be indented or stepped below the containing object. You can use the dot operator to traverse the hierarchy. For example, the Range object is accessible as Application.Workbooks(1).Worksheets(1).Range.

Automation Overview 21

In the automation diagrams, heterogeneous collections are indicated by a gray box with a dashed outline rather than a solid outline. Excel refers to these as metacollections.

Demo 2: Driving Excel through Automation


This demonstration illustrates the nature of automation capabilities. Microsofts Excel is an automated application. This enables you to interact programmatically with the spreadsheet software. Through this approach, you can reduce the number of manual steps your users would normally follow in their daily tasks. In preparation for this demonstration, an Excel macro was created and stored in the personal workbook. Additionally, some data was extracted from pole features and stored in a text file (comma-separated value format .csv). The automation program is written in Visual Basic. The input to the program is the name of the data file. The program then starts Excel and loads the data into the worksheet of a new workbook. The data is selected and the macro is run. The result of this process is a chart indicating the number of poles that need service each month. Although this is quite trivial alone, it is indicative of the type of control you can exert over applications through automation. Automations foremost benefit is in automating the end users tasks by reducing manual steps. The instructions for programming this example and the solution are available with the lab materials under ExcelDemo.

22 Fundamentals of GeoMedia Development Part I

GeoMedias Automation Capabilities


GeoMedia Concepts
GeoMedia is a viewing and analysis tool for geographic information. GeoMedia lets you integrate data from multiple sources and multiple formats into one map and perform sophisticated queries for spatial analysis. You can either use GeoMedia as an end-user product or as a development platform to build customized applications. GeoMedia allows you to do the following: Display multiple geographic data types simultaneously without translation. GeoMedia uses coordinate transformations so you can view data from numerous standard data sources as an integrated map. As a product, GeoMedia automates this process and requires only a minimal knowledge of projections and coordinate systems. As a custom application developer, you need to have a working knowledge of coordinate systems and projections. Perform spatial analysis through buffer zones, spatial and attribute queries, and thematic maps. Control the contents and appearance of your map window through the interactive legend, including the display of scanned images.

There are, of course, many more capabilities within GeoMedia. GeoMedia works in a client / server configuration. GeoMedia is the client. The data (or warehouse) may reside on the client machine or on a remote machine. The warehouse or database contains the geographic data. All access to a warehouse is performed through a software component known as a GDO server. Although GeoMedia only reflects the changes of a single user, it is a possible to have many GeoMedia clients access the same warehouse data. The GDO servers are resident on the client system and access the warehouse on the remote system as needed.

GeoMedia Terminology
GDO
Geographic Data Objects (GDO) is an extension to OLE which enables clients to access geographic data from disparate sources in a predictable manner. With GDO, we have created a specification for an OLE Automation server that may be accessed via automation clients such as Visual Basic.

Automation Overview 23

Intergraph participates in Open GIS Consortium (OGC) activities to define an international standard for access to geographic data. The GDO specification has been presented as that standard. GDO follows the example of Microsofts DAO and RDO technologies for data access. These have been Microsofts OLE Automation objectoriented standards for accessing and manipulating databases. These paradigms match the needs of geographic data access quite well; GIS can be considered a database problem with the additional problems of geodetic coordinate systems, geometry, and graphics display. GDO addresses these additional problems with GIS specific interfaces. However, GDO does not take on the responsibility of database technology interfaces because many data sources are not true databases. It follows the paradigm for its familiarity and usefulness, but does not require the sophistication of a database. In this light, GDO specifies the way to access data, but does not mandate any of the technology for the replication of data, backup and recovery, security administration, or multi-user access that may be commonly associated with a database.

GRecordset
A GRecordset object contains all database records that meet a specified criterion. All GRecordset objects are constructed using records (rows) and fields (columns). By exposing the geographic data as a GRecordset, we enable data manipulation. GRecordset objects are equivalent to cursors containing data from the database. The cursor is the result of posing a query to the database. Information about attributes or columns of a GRecordset is accessed and manipulated via a collection of Gfields, which are akin to columns selected by the query. Through this common structure clients are able to access and manipulate information from a variety of data sources in a standard way. The terms GRecordset and recordset will be used interchangeably in this material. NOTE: A recordset is not a collection, although there are similarities. A recordset is a single object in which the rows are accessed much like an array using the MoveNext method or by setting the Bookmark property as you would an array index. If the recordset were a collection, you would access an individual object for each row. We will use several terms that are very common in database environments that are synonyms for the GeoMedia terms. GDO Term Database Other Synonyms

24 Fundamentals of GeoMedia Development Part I

GDatabase GTableDef GField GRecordset Active row (bookmark)

Database Table Column Cursor Current row

Warehouse, server Feature Class Attribute, field Recordset Feature instance, row

Legend
The legend is an important part of GeoMedia. It is the display control center for the map window. Unlike a traditional legend that only reflects what appears in a map, the GeoMedia legend is interactive, allowing you to dynamically control the map. Through the legend, you control which feature classes, queries, thematic maps, labels, and images appear in the map window and how they look.

Pipe
GeoMedias architecture includes a concept known as a pipe. The pipe philosophy defines a protocol that allows software components to interchange data in a common fashion through GRecordsets. As such, GeoMedia includes several pipe components that create and/or manipulate data through GRecordset objects. Pipes are the mechanism by which GeoMedia packages table-related functionality in a way that fosters the reuse of data and the manipulation of data by specialized software components. Pipes consume one or more input GRecordsets and produce one or more output GRecordsets. The output GRecordset of a pipe may have more rows, fewer rows, more fields, or fewer fields than the original input GRecordset. This output GRecordset can in turn be fed into another pipe which may further process the data contained in the GRecordset.

Coordinate System
A coordinate system is a way that GIS locations are stored. The amount of data contained in the coordinate system is relative to its accuracy and detail. A more detailed coordinate system definition provides a more precise description of geographic positions. GeoMedia stores geographic data with reference to one of many possible coordinate systems. These coordinate systems provide the mathematical basis for relating the features in your study area to their real-world positions. GeoMedia supports two categories of coordinate systems:

Automation Overview 25

Projected coordinate systems express coordinates as X,Y,h, where X normally points east on the plane of the map, and Y points north at the point chosen for the origin of the map. The X coordinate is called easting; the Y, northing. The h represents height. Projected coordinate systems differ in how they represent the curved surface of the earth on the flat surface of a map. Geographic coordinate systems express coordinates as lon,lat,h, where lon (longitude) is the angular distance from a zero meridian, lat (latitude) is the angular distance from the equator, and h is height.

GeoMedia interprets coordinates with reference to a geodetic datum, which defines precisely the reference ellipsoid and its position relative to the surface of the earth. The ellipsoid is the model used to represent the shape of the earths surface.

Feature Class
A feature class is a classification of data. In GeoMedia, this maps to a table in the data server. Every data instance is assigned to a feature class. For example, a data set generally consists of several feature classes, such as roads, bridges, schools, and churches.

Feature
A feature is a geographic entity that is represented on a map by geometry and defined by nongraphic attributes in the database. The definition of these attributes and geometry is stored in a feature class. A feature, or instance, is equivalent to a row in the feature class table.

GeoMedias Automation Model


GeoMedia contains many automated objects. The volume of automated objects makes GeoMedia both very powerful and very overwhelming. In order to better understand the objects, well first review the automation diagrams. The first part of the automation model that we will review is the overall application structure.

26 Fundamentals of GeoMedia Development Part I

As we look at the document, note the differences in boxes. These differences provide insight as to the nature of the object. Boxes that are dark green represent both a collection and an object. Boxes with a heavy border only function within the GeoMedia application. Boxes that are dark green and have a hatched pattern are metacollections. Recall that a metacollection is a collection that contains more than one type of object. Aqua boxes are simply objects. Blue boxes are simple objects but are a heterogeneous member object. For example, the legend entry contains a style object property. That property may be any of the GeoMedia style objects.

The following rules can be applied when you are navigating the automation diagrams:

Automation Overview 27

When you encounter a homogeneous collection, add an s to the object name. If the object name ends with a y, replace the y with ies to make the collection name. For example, Application.Document.Connections and Application.ActiveWindow.MapView.Legend.LegendEntries. If you are manipulating an object in the collection, remember to add the index into the collection. For example, Application.Document.Connections(1).ConnectionName. When you encounter a heterogeneous collection, skip the next object as you continue through the hierarchy. For example, Application.Document.Windows(1).Mapview.Visible When you encounter a heterogeneous object, substitute the actual object in its position and continue your navigation.

Note: These diagrams show objects and their dependent objects. In many cases, the dependent object is represented by its property name. For example, the QuerySubFolders collection is the property name on the QueryFolder object. The actual object type is QueryFolders. This section will briefly review each object. Subsequent sections of the workshop will provide more detailed information.

Application
Starting from the upper left corner of the diagram, we have the following member and dependent objects for the Application: Windows a collection of all the open windows (data or map) within the application Active Window the window that has focus. This is either a DataWindow or a MapWindow in the Windows collection. PreferenceSet an object that provides access to the GeoMedia preference information stored in the registry UnitsOfMeasure an object that provides conversion services for measurement units (e.g., feet, meters) Category / Command the classifications and commands defined by GeoMedia as well as custom commands Menubar / MenuItem the menubars that control the user interface and the items within each menu Accelerator the short cut definitions for commands (e.g., F1 for

28 Fundamentals of GeoMedia Development Part I

help) Toolbar / ToolBarButton the toolbars that control the user interface and the buttons within each bar DockableControl a GeoMedia window-like container for ActiveX controls Document the geoworkspace object

The Document object is the most significant one within this set because it provides access to all of the data and display capabilities of GeoMedia. While your data is stored in an application (FRAMME, MGE) or a database (Access, Oracle SDO), your display definitions, queries, and transformations are stored in the geoworkspace (document). While data can be accessed through multiple documents, the definitions stored in the workspace are unique to that workspace. GeoMedia supports a single document interface and does not allow multiple documents to be opened simultaneously. Because many objects have an inherent association with the document, you must be sure that you release any references to these objects before the document is closed.

Document
Continuing through the diagram, the following objects are associated with the Document. Connections collection of Connection objects that provide access to the GDO (Geographic Data Objects) servers and to your data Windows collection of windows open on this document (same as Application.Windows) MasterLegend a special instance of a legend object that GeoMedia uses to assign the default style to recordsets Legends collection of named legend objects QueryFolder this object contains the collection of query classifications, each containing a collection of query objects SelectedObjects the set of selected objects within the active document enabling the highlighting of the same object in multiple windows CoordSystemsMgr object governing the definition of projections and transformations. This object also provides the default coordinate system for each map window. SpatialFilters collection of geometry objects that can be used to limit the area of interest associated with a connection

Automation Overview 29

PropertySet stores miscellaneous user-defined data ColorSchemes collection of color palettes used in unique and range legend entries

As we know, the Windows collection is a metacollection in that it contains two types of objects, MapWindow and DataWindow. The DataWindow is simply a container for the DataView custom control. The DataView enables you to review the attribute information associated with all of the rows in a recordset.

MapWindow
The MapWindow hosts three controls: MapView, NorthArrow, and ScaleBar. Each of these controls provides information to assist the user in interpreting the display of the geographic data. NorthArrow an OLE control that indicates the true north position relative to the data displayed and the coordinate system of the MapView ScaleBar an OLE control that indicates the scale of the data displayed in the MapView (e.g., 1 paper = 100 ft. ground) MapView an OLE control that displays the geometric definition of GIS data

The MapView is the key to the display of vector data and images. The Legend member object defines which recordsets to display and in what order. The CoordSystemsMgr member object defines the projection used to display the data. Legend object which manages the display of data in the MapView LegendEntries collection of legend entries in which each entry holds a recordset object and its associated style for display HighlightedObjects collection of objects that are highlighted in the MapView to help distinguish the elements and make selections MapViewSelectedObjects collection of objects within the MapView that are also in the SelectedObjects collection on the Document CoordSystemsMgr object governing the definition of projections and transformations for this particular MapView

Coordinate Systems
The CoordSystemsMgr is the primary object governing all activities associated with the coordinate system. The CoordSystem member object defines characteristics of a particular GIS coordinate system. These

30 Fundamentals of GeoMedia Development Part I

characteristics include the storage resolution and range, as well as ties to the projection, geographic, geocentric, and paper reference spaces.

CoordSystem object which defines a particular GIS coordinate system. RefSpaceMgr object which defines a set of reference spaces based on a common geodetic datum and a set of algorithms for transforming coordinate points among the members of that local set of reference spaces. UnitFormatSpec stores units and formatting information. This object formats and parses value and point strings representing distance and coordinates. GeogSpace object which specifies and retrieves the ellipsoid and geodetic datum used to define the geographic reference space within the RefSpaceMgr object. PaperSpace object which controls the nominal paper map scale and

Automation Overview 31

returns and adjusts the projection-to-paper matrix. This matrix is used internally by the RefSpaceMgr object to transform points between the projection and paper space. ProjSpace object specifies and retrieves the projection algorithm used to define the projection reference space within the RefSpaceMgr object. This object also allows modification of the projection algorithm parameter settings. AltCoordSystemPaths a collection of AltCoordSystemPath objects each of which contains a chain of transformations from the CoordSystem of the current CoordSystemsMgr object to other transformations. LeastSquares uses least squares mathematics to perform controlpoint-based registration between two sets of coordinate points DatumTransformation defines a horizontal geodetic datum transformation model and defines its parameters for the transformation of coordinates between different geodetic datums

Legend
As you know, the legend controls the display characteristics of the data. The legend contains a collection of legend entries. The order of the legend entries controls the display priority of the data. A recordset object (GRecordset) is associated with each legend entry. Additionally, a style defines the visual characteristics of the data associated with the legend entry. Each legend entry object responds to similar properties and methods. The differences in the types are related to the need for different display mechanisms for different data types. All geometric recordsets can be displayed as RecordLegendEntry. Recordsets associated with raster entries require different display techniques and thus are displayed with the RasterLegendEntry.

32 Fundamentals of GeoMedia Development Part I

RecordLegendEntry type of legend entry that displays all geometry in the recordset with the associated style RasterLegendEntry type of legend entry that displays a single image from the specified recordset RangeLegendEntry a thematic legend entry that divides the input recordset into N ranges based on statistical analysis UniqueValueLegendEntry a thematic legend entry that divides the input recordset into N sub recordsets by grouping all of the rows from the recordset that have the same value for a specified field into a new recordset Style an object which contains display characteristics like color, weight, and style TitleFont, SubtitleFont, HeadingFont Microsoft font object which controls the font used for text display on the legend Range an object that specifies the display characteristics of the sublegend entry and indicates the ranges of the associated data

Automation Overview 33

UniqueValue an object that specifies the display characteristics of the sublegend entry and indicates the value associated with this set of data DisplayedObjects object type of the HighlightedObjects and MapViewSelectedObjects containing a list of elements to highlight or select RecordsetObject reference to an entire recordset for highlight or selection purposes RecordObject reference to a single row in a recordset for highlight or selection purposes GeometryObject reference to a single row in a recordset identified by a graphic point for highlight or selection purposes RasterObject reference to a single image for highlight or selection purposes

GDO
In GeoMedia, most all operations center around data access. GDO is the hub of that access. We use the recordset as the primary medium for communication between software components. All data servers support the GDO interface for accessing definition information and data.

34 Fundamentals of GeoMedia Development Part I

GDatabase object which provides primary access to the data and definitions GTableDef object which defines the structure of the data where a single object defines one feature class or table in the database GField object which defines one column in the database of a given table GIndex object which indicates the field upon which a tables database index is created for improving data retrieval GRecordset object containing data from the data server GError object indicating errors that occurred during processing GFRMAdminExtension object containing administrative information for FRAMME servers GFRMSeg object specifying the segment name and number for FRAMME servers ExtendedPropertySet an extension object available on OriginatingPipe based recordsets which provides metadata information

Automation Overview 35

Name an extension object identifying the associated Query object for the recordset Notification an extension object which provides access to methods needed to refresh a recordset when the criteria is changed Errors an extension object which provides access to the GErrors collection of the underlying database CoordSystem an extension object that provides a GRecordset object containing the coordinate system definition for the associated geometry field

Geometry and Styles


A GIS system without geometric data is like a fish out of water. GIS applications present and analyze spatial data. The geometry objects are the visualization of that spatial data. The geometric data storage is defined by the server. In traditional applications like FRAMME and MGE, the storage was in binary files. In the Access and Oracle SDO servers, the storage is as coordinate values in the relational database. Through GDO, all servers provide the geometric data in a binary (blob) format. To operate more effectively on the blobs, GeoMedia converts the data from a blob to a geometry object. All of the geometry objects are automated objects. This simplifies the process of manipulating the object because the manipulation of the binary format is isolated to the geometry objects and the geometry services you do not have to create the blob format. Most presentations of GIS data would not be very interesting without styles. A style is a definition of the color, weight, and pattern associated with an element. We support styles for each classification of geometry objects. However, most style objects can be applied to any geometry object.

36 Fundamentals of GeoMedia Development Part I

GeometryCollection a set of geometry objects that represent a particular spatial object PointGeometry an object defining a point Origin X, Y, Z coordinate values Vector I, J, K coordinate values representing a vector in 3D space Matrix a 4 x 4 matrix OrientedPointGeometry an object defining a point with orientation TextPointGeometry an object defining a point that has an associated text string or label LineGeometry a two-point vector PolylineGeometry a vector defined by an unlimited number of points RectangleGeometry an object defining a rectangle PolygonGeometry an object defining a closed shape (area) with an unlimited number of points

Automation Overview 37

BoundaryGeometry a special type of closed shape which might contain holes or cut outs within the shape (area) Holes collection of rectangle or polygon geometries that define the cut-outs within a boundary RasterGeometry an object defining the display characteristics and the bounding polygon for the image ArcGeometry an object representing a circular arc in some plane in 3D space CompositePolylineGeometry collection of a geometries that form a single continuous polyline CompositePolygonGeometry collection of geometries that form a single continuous closed shape

AreaStyle definition of style characteristics for gdbAreal types of geometry AnyStyle definition of style characteristics for gdbAnySpatial types of geometry TextStyle definition of style characteristics for gdbGraphicsText types of geometry LinearStyle definition of style characteristics for gdbLinear types

38 Fundamentals of GeoMedia Development Part I

of geometry BitmapStyle one of the definitions of style characteristics for gdbPoint types of geometry SymbolFontStyle one of the definitions of style characteristics for gdbPoint types of geometry HandleStyle definition of style characteristics for handles displayed in selected data for edit operations PointSymbolStyle one of the definitions of style characteristics for gdbPoint types of geometry PatternedLinearStyle one of the definitions of style characteristics for gdbLinear types of geometry PatternedAreaStyle one of the definitions of style characteristics for gdbAreal types of geometry

Pipes and Services


GeoMedias model contains many objects that are not dependent on the application object. Many of the objects presented in the previous sections, although navigable from the application, can exist independently of the application. In this section, we present a large set of objects that are not in any way dependent on the application object. The Controls group includes all of the GeoMedia custom controls. The Services group includes software components that accept some set of input, perform calculations, and return a set of answers. The Pipes group contains software components that accept some input (possibly including recordsets), perform a calculation, and output a new recordset. This is the primary distinction between pipes and services. Pipes always output a recordset, while services provide discrete answers.

Automation Overview 39

AttributeFilterPipe pipe object which filters or reduces a recordsets number of rows based on an SQL attribute filter BufferZonePipe pipe object that creates new geometry based on the geometry in the input recordset SpatialQueryPipe pipe object that spatially compares the two input recordsets CSSTransformPipe pipe object that performs a coordinate transformation on the geometry of the input recordset OriginatingPipe special pipe object that creates an initial recordset adding value to the GDO recordset (Name, ExtendedPropertySet, Notification) SortPipe pipe object that orders the input recordset SortKey object supporting the SortPipe CenterPointPipe pipe object that calculates the center of a geometry EquijoinPipe pipe object that creates a new recordset by joining two

40 Fundamentals of GeoMedia Development Part I

input recordsets GraphicsTextPipe pipe object that creates a text geometry by calculating the label from attribute values MovePipe pipe object that moves geometry SchemaProjectPipe pipe object that allows fields to be hidden SpatialFilterPipe pipe object that spatial constrains the rows in its output recordset StatisticsService component that statistically analyzes the input recordset GeometryDigitizeService object supporting viewing of geometry objects that are not currently stored in the database (during creation or for temporary objects) GeometryEditService object that supports geometry edit operations GeometryStorageService component that converts between geometry blobs and geometry objects ServerTransService component that provides methods for performing common coordinate system operations RasterPropertiesService object used for extracting information from an image file and for creating a transformation matrix MeasurementService object calculating the area, length, partial length, and perimeter of a geometry object MetadataService object which sets and retrieves feature class definition information to supplement the GDO GTableDef object TableProperty MetadataService support object FieldProperty MetadataService support object SmartLocateService service object for finding elements within a specified geometric region AutoPanService service object for automatically adjusting the view as the cursor nears the map window edge OutputTableService service object for saving recordsets to tables SnapService service object to assist in snapping to geometry elements SymbolFileService service object for loading symbol objects for use in the style definitions

Automation Overview 41

GMMapView OLE control which defines the MapView object GMDataView OLE control which defines the DataView object GMDefCoordSystem OLE control which supports the interactive definition of a coordinate system GMEventControl OLE control that receives events from the MapView and fires them to your form GMFeatureCombobox OLE control for displaying feature classes and queries on custom forms as a combobox GMFeatureListbox OLE control for displaying feature classes and queries on custom forms as a listbox GMNorthArrow OLE control which defines the NorthArrow object GMScaleBar OLE control which defines the ScaleBar object GMWebBrowser OLE control which supports the integration of

42 Fundamentals of GeoMedia Development Part I

Internet Explorer GMPlacement OLE control used during feature placement to select a feature and geometry type GMProperties OLE control used during feature placement and editing to gather attribute values. Use of this control during development requires a license of True DBGrid Pro 5.0 from Apex Software Corporation. Upgrades are available from the DBGrid component provided with Visual Basic 5.0. Visit their web site for more information: http://www.apexsc.com/. GMTextPlacement OLE control used during interactive text placement GMPrecisionCoordinate OLE control that supports coordinate readout PickQuickDialog dialog that assists users distinguish multiple elements during a highlight operation PageSetup command object used in independent applications to initiate the mapview page setup Print command object used in independent applications to initiate the mapview print operation GMFeatureComboboxInput OLE control that creates a recordset GMFeatureListboxInput OLE control that creates a recordset GMQueryStorage OLE control that stores recordsets in query folders GMTableStorage OLE control that outputs a recordset to a GDO table GMLegendEntryOutput OLE control that creates a legend entry for a recordset GMDataWindowOutput OLE control that displays a recordset in a data window GMJoinProperties OLE control that provides a GUI interface for the EquijoinPipe GMLabelProperties OLE control that provides the GUI for specifying the label content EventServer object which allows events from multiple map windows to funnel into a single event control

Automation Overview 43

MapViewListeners object which manages commands that are listening to events in MapViews GeoMathUtilities a C function library of math functions callable by automation clients

IMPORTANT: Use the automation help to find more details on each of the objects. Initiate Programming Utilities and select GeoMedia Object Reference. You may also select the help icon from the Visual Basic Object Browser.

Lab 1: Navigating the GeoMedia automation model


In this lab, you will use the automation diagram to find the requested objects in the hierarchy. Each lab step will ask you to create a reference to a particular object or property within the automation model. The answer can be a single statement that uses the navigation (dot) operator. You will need to use the automation diagrams presented in this section as well as the Automation Help and the Visual Basic browser.

Exercise setup:
1. From the GeoMedia program group or from the Start Menu, select Programming Utilities. Select GeoMedia Object Reference. This will provide access to all of the help topics. 2. Start Visual Basic and open the project in c:\TGM\Labs\Lab01\src\GeoMediaCommand.vbp. This will provide you with access to context sensitive help on each object. 3. Open C:\TGM\Labs\Lab01\NavigationLab01.txt with Notepad. Use Application or gobjGeoApp to refer to the application object for the exercises. As we will see in the next section, GeoMedia commands are initialized with two global objects: gobjGeoApp and mobjGeoViewListeners. The former is a pointer to the GeoMedia application object. The latter is a pointer to the set of commands actively listening for events on the map views. 4. Specify the answer in the text file. Use the help to assist you in finding the correct property names. Problems 9 and 10 are extra credit.

44 Fundamentals of GeoMedia Development Part I

Approaches to Customization
As with many of Intergraphs GIS products, customization capabilities are a very important aspect of the product. Additionally, many products which have traditionally served as out of the box applications also allow you to configure or modify the interface to the product. GeoMedia offers three mechanisms for customizing the product. The approach to customization will depend on your requirements, your level of programming expertise, and the suitability of the standard GeoMedia interface to your needs. These three approaches can be viewed through the following diagrams.

Commands

Custom Command DLLs

GeoMedia.exe Object DLLs


Using this technique, GeoMedia is enhanced with command DLLs and the GeoMedia object DLLs. Recall the discussion of in-process and out-ofprocess execution of software components. In this model, during normal operation, there is a single process executing so all components are inprocess.

Automation Overview 45

Custom Application

Custom.exe Object DLLs


Using this technique, you build your own executable using GeoMedias objects. There is again only a single process executing.

Driving GeoMedia

Object DLLs Custom Command DLLs

Custom.exe

GeoMedia.exe Object DLLs


In this approach, there are two separate programs executing.

Customizing GeoMedia through menus and commands


In this approach, you begin with the GeoMedia application. You may create a new set of GeoMedia commands that augment the GeoMedia commands or perform tasks in an order more suited to your environment.

46 Fundamentals of GeoMedia Development Part I

We will see how to create commands in the next section of the workshop. The simplest approach to customization involves only tuning the GeoMedia menus. You may remove menu items that you do not need or do not want your user to access. The Tools > Customize command can be used to configure the menus and the keyboard accelerators. An accelerator is a keystroke defined by the application to give the user a quick way to perform a task. An accelerator is also known as a short-cut key. For example, pressing the control key (CTRL) and N is equivalent to the File > New GeoWorkspace... command selection. You can remove menu items from the menubars. There are three types of menus available for modification: Map menubar that displays when a map window is active Data menubar that displays when a data window is active None menubar that displays when no document is open

If you want to remove or reorder commands that exist in all window types, you will need to remove them from each of the menu types. Menu and accelerator customization is stored in the registry at HKEY_CURRENT_USER\Software\Intergraph\GeoMedia\02.00 under Menus and Keyboard, respectively. Since they are stored in this location, it is possible to have different menu configurations for different types of users who might share a single computer. If you are configuring an environment for several users, we recommend that you write a command or application which utilizes the applications automation model (MenuBar/MenuItem, Accelerator, Category/Command, ToolBar/ToolBarButton) to configure your menus. If you find that you need more commands than GeoMedia provides, you will need to write these and add them to the GeoMedia command set. You will need to move your custom commands to every machine. They can reside in any directory that you choose. You will need to install each command. This will register the command so that the GeoMedia framework can create it (with CreateObject) and add it to the GeoMedia command set. The installation syntax is:
c:\Program Files\GeoMedia\Program\Installusrcmd.exe MyCommand.dll MyCommand.ini

Substitute the appropriate installation location when accessing the executable. If you are not in the directory containing the .dll and .ini files, include the full path. The .ini file is created when the command is created through the GeoMedia Command Wizard. It contains information about the command, its tool tip and status prompt, and the enabling conditions for the command. It is possible to create multiple commands in a single DLL to reduce the number of files that must be delivered.

Automation Overview 47

Note: Installing Sample Commands: If a command is accompanied by a GMSampleXXX.txt file, you can use the Programming Utilities module to install the sample command in lieu of installusrcmd.exe. You will also need to add menu items for your custom commands. If you have commands that are applicable to all windows, you will need to add them to each of the menu types. You can also create custom workspace templates. Through the templates, you can define standard connections, legends, and queries that your user will utilize on a frequent basis. You can also define the displayed windows and the status of the legend entries. The advantages of customizing GeoMedia through command creation and menu configuration are: quicker start up availability of all window and document-management functions automatic persistence of display environment and options incremental expansion of capabilities ability to focus development and testing only on additional end-user capabilities

As you will see when we create a custom application, there is a significant amount of development work associated simply with maintaining the application framework. By customizing GeoMedia through commands, you can focus your efforts on end-user functionality. Note: DLLs generated with PowerBuilder 5.0 cannot be called by external applications. The GeoMedia command framework creates commands as in-process OLE servers. Since you cannot do this in PowerBuilder, you will have to create a VB wrapper command that can then communicate with the PowerBuilder.Application object. Because the application will be out-of-process, you need to be sure and create any persistable GeoMedia objects through the Application.CreateService method. You should also use this method for any objects that are arguments or properties of other objects created with the method.

Custom applications using GeoMedia objects


Another approach to GeoMedia development is to create a custom application using the GeoMedia objects. In this scenario, you develop

48 Fundamentals of GeoMedia Development Part I

your own framework, including window management, document management, and persistence. You then utilize the automated objects in your commands and application processing to perform the desired analysis. In this case, you will create an executable and, possibly, supporting DLLs. Your executable and any supporting DLLs you have created may utilize GeoMedia DLLs. This approach is often taken when the end user is granted very little flexibility in using the product. For example, you may not want to allow the end user to change the legend configuration that you have defined. In GeoMedia, we do not provide any option for a read only legend. In the automation diagrams, all public GeoMedia objects can be used in custom applications except those that are explicitly associated with the framework (application). These objects are: Table 0-2 Application Category(s) MenuItem(s) DataWindow SelectedObjects GMFeatureListbox GMFeatureCombo boxInput GMTableStorage Windows Command(s) Accelerator(s) MapWindow MapViewListeners ToolBar(s) GMFeatureListbox Input GMLegendEntryOut put ActiveWindow MenuBar(s) Document MasterLegend GMFeatureCombobox ToolBarButton(s) GMQueryStorage GMDataWindowOutput

All of these objects require some information associated with the application or document, therefore they are only creatable within the context of the application. That is, GeoMedia must be running for these objects to exist. With a custom application, you are responsible for delivery and registration of the GeoMedia components that you use. The standard mechanism is to install GeoMedia and then install your application. This will require a full GeoMedia license and provides the user with the ability to use the full product. You are required to include the GeoMedia copyright information in the delivery of your application. This is usually specified in the applications Help > About MyApp... command. Intergraph will discuss opportunities with individuals and third-party developers to purchase object bundles. Please contact the Team

Automation Overview 49

GeoMedia Technical Staff (techtgm@ingr.com) to discuss such an OEM (Original Equipment Manufacturer) agreement. The object bundles are divided by sets of functionality that would comprise the application. For example, a simple viewing application requires a certain set of objects, while an analysis application would require additional objects. Refer to Object Bundles in the Appendix for the object breakdown. The advantages of creating a custom application with GeoMedia components are: ability to strictly control the user workflow ability to specify the complete look and feel to match other products used in your workflow reduction in application footprint by eliminating unused components

Note: A custom application is the only logical option for PowerBuilder users since it does not support other applications calling into its DLLs. If you have arranged an OEM agreement with Intergraph, you may not install the GeoMedia application on the end-user machine. You must include the GeoMedia component installation and registration in your custom setup.

Driving GeoMedia
One final option for customizing GeoMedia involves creating a custom application that runs or drives the GeoMedia application object. In the prior discussion, you used objects from GeoMedia that were NOT related to the framework. In this approach, you will create an application (.EXE) and then create the GeoMedia application or attach to an existing instance of GeoMedia. Hence, two separate executables will be active. This is similar to the lab exercise in which we wrote a Visual Basic application to drive Excel. You then have access to all of the GeoMedia automation models. In this way, you get all of the benefits of the GeoMedia framework, but you are able to restrict access or control the users workflow. GeoMedia objects should be created using the Application.CreateService method rather than CreateObject directly. This ensures that all objects are created within the GeoMedia process and share the same memory space.

50 Fundamentals of GeoMedia Development Part I

Summary
The primary objective of this section was to familiarize you with automation capabilities and to prepare you for GeoMedia customization. To this end, we discussed basic object-oriented techniques and OLE/COM. We focused on the topic of automation within the realm of OLE. You should be able to define these terms: Automation client/controller Automation server/object Object Property Method Collection Dot/navigation operator GUID, ProgID Interface

You should understand these fundamental GeoMedia concepts: GDO Pipes Legend Coordinate System Features

You should understand an automation diagram and be able to traverse it. Finally, you should understand the options for GeoMedia customization. The next section will investigate the first customization option: adding GeoMedia commands.

Automation Overview 51

Can You Answer These Questions?


1. What is the purpose of Team GeoMedia? 2. What does COM stand for? 3. When you hear the word Automation, what two words come to mind? 4. What are the benefits of OLE? 5. What three ways can be used to customize GeoMedia? Give an example of each. 6. How many legend entry types are there? 7. What is the component hierarchy in GeoMedia from Application to RecordLegendEntry? 8. In your program, you are iterating through the legend and examining each entry. How do you know the type of the legend entry? 9. Given the following definition, provide two other ways to create an instance of the object. Dim objMD as Object Set objMD = CreateObject(GMService.MetadataService)

52

Creating a Custom Application


Introduction
In this section, you will be creating an independent custom application using Visual Basic as the automation controller or client (scripting language and application) and the GeoMedia objects. This is a very common approach to customizing GeoMedia. Many customers have the requirement to create their own independent applications using the GeoMedia objects (and perhaps automation objects from other applications). There are several reasons why this may be the best approach for your application. One reason is that you are building an application where GeoMedia functionality is only a small part of the overall application. It may be easier to create this application from scratch, and then in the appropriate places call GeoMedia functionality to perform certain necessary GIS tasks. Another reason would be that you want to limit the flexibility and functionality of your user much more so than you could simply by customizing the existing GeoMedia framework application. It may be that your requirements dictate a different look and feel of your application than GeoMedia provides. And, as already mentioned, if one of the requirements is that your application be developed using PowerBuilder, this is the most logical approach since PowerBuilder does not support other applications calling into its DLLs. This section of the workshop discusses this particular approach to customizing GeoMedia. In the first lab of this section, you will add a small amount of code to an existing Visual Basic project. That first lab will primarily focus on familiarizing you with an application which has been built for you its framework, menus, windows, and forms. For the remainder of this workshop, you will be adding functionality to this same project, each lab building upon the previous one. By the end of this section, you will have built quite a functional application. This Visual Basic project is designed to output a single executable which utilizes both Visual Basic objects and GeoMedia objects contained in their delivered DLLs. It will run stand-alone independent of GeoMedia. This means that GeoMedia is providing the necessary functionality in the background. You are not actually running the GeoMedia product you never see its application framework running. While this approach gives you the application developer much more flexibility, it also means that you have more initial work to do that is provided for you when you add commands to GeoMedia. For purposes of this class, the framework and windows management portions of the application have already been provided in the lab templates.

53

54 Fundamentals of GeoMedia Development Part I

Topics
1. Connecting to the GDO Server 2. Creating Recordsets 3. Adding a MapView and Displaying Data 4. Creating and Displaying Queries 5. Creating a Data View 6. Custom Application Limitations

Objectives
At the end of this section, you will be able to do the following. 1. Explain the independent application approach to GeoMedia customization 2. Use these GeoMedia objects: GDatabase MapView Style GRecordset Legend DataView GField LegendEntries

3. Implement a GeoMedia custom application

Labs
2. Application Framework and Connecting 3. Creating and Manipulating Recordsets 4. Constructing the MapView 5. Optional: Styles 6. Optional: Marginalia 7. Optional: Printing 8. Spatial Query 9. Buffer Zone 10. Locate 11. Optional: Data View 12. Optional: Multi Key Sort

Creating a Custom Application 55

Connecting to the GDO Server


Typically, one of the first actions your application will have to do (or allow the user to do) is make a connection to an existing GIS database what GeoMedia calls a warehouse. This is accomplished via functionality in one of the GDO servers. For example, if you need to connect to an MGE database, you will be using the MGE GDO server; for Access, the Access GDO server.

GDatabase GTableDef GField GIndex GField GRecordset GField GError


Specifically, this is accomplished by creating a GDatabase object, and then calling its OpenDatabase method. Dim objAccessDbs As GDatabase Set objAccessDbs = CreateObject (Access.GDatabase) objAccessDbs.OpenDatabase D:\wherever\myDB.mdb Note: When creating a GDatabase object, you will need to use the above method so that the appropriate GDO servers GDatabase will be created. You accomplish this by specifying a particular GDO server as the prefix of the ProgID passed to CreateObject. The optional Visual Basic syntax for creating an instance of an automation object Dim objAccessDbs As New GDatabase will not work.

56 Fundamentals of GeoMedia Development Part I There are nine different GDO servers. The prefix for the ProgIDs are as follows. Server Type Access ArcInfo Oracle Spatial Cartridge MGE FRAMME MGE Segment Manager ArcView MGDM CAD Server Prefix Access AI GW MGE FRAMME MGSM AV MGDM GCAD

Establishing access to the GIS data from the GDatabase object may suit your purposes well. However, you may want to take advantage of some GeoMedia functionality that requires that you actually start creating objects at a higher level in GeoMedias automation model. Specifically, you may want to use the GeoMedia Connections collection and Connection object. For example, if your application is going to allow more than one connection, the Connections collection can serve as a dynamic data structure for the multiple databases your user might access. Also, if you want to take advantage of the MetadataService or create OriginatingPipe objects, you must use the Connection object. You can accomplish the same functionality as above with GDatabase by doing the following with Connections: Dim objConnections As New Connections Dim objConnection As Connection Set objConnection = _ objConnections.Add(D:\wherever\myDB.mdb) With objConnection .Type = "Access.GDatabase" .Location = D:\wherever\myDB.mdb .Connect End With Now, you have the ability to add additional connections in a like manner, and you can use the services mentioned above.

Creating a Custom Application 57

Debugging Your Application


Interactive debugging within the Visual Basic development environment is very intuitive. Certain general rules should be applied in the development of your application for successful development and debugging. For any functions or procedures that manipulate objects in some way such that they might encounter errors, you should always include an error handling clause. Refer to the Err Object documentation in VB help for more information on this construct. Additionally, you should always include Option Explicit in every file in your project. This forces method and property names as well as argument sequences to be checked during compilation. Finally, use strong typing wherever possible rather than Object declarations. You can run your program interactively or compile and execute it. During initial development, you will want to run the program from within the Visual Basic project environment. Open your Visual Basic application project. Set any breakpoints needed in the source code. Select the Run > Start (or the Start button). When your application command is selected, you will break at the locations you set. All normal Visual Basic debugging capabilities are available to you. Always continue (with the Start command) at the end of your functions and subroutines. You can stop debugging at any time to terminate your application. When you have made code corrections, select Run > Start again and repeat the process. To avoid causing a crash on exit from the application, be sure and release all variables whenever their use is no longer required. If a part of your command is not suitable for interactive debugging, you will need to use status prompt messages and/or MsgBox calls to diagnose the cause of your errors. You can use the application status bar to display information messages about your command progress. This call is: MfrmMain.stbMainStatusBar.SimpleText = _ Step 1 preparation This technique is less intrusive than a message box. If you opt for message box displays, you should consider writing a DebugMsgBox function. For example:

58 Fundamentals of GeoMedia Development Part I Global Const iCurrentSeverity = 5 Public Function DebugMsgBox( iSeverity As Integer, _ strPrompt As String ) As Long If iSeverity >= iCurrentSeverity Then DebugMsgBox = MsgBox strPrompt, _ vbOKOnly + vbExclamation, _ My Command Title Error Else DebugMsgBox = vbOK End If End Function With this type of function, you can retain your diagnostic information without continual editing of your code while controlling the extent of the debug information displayed. To turn off diagnostics completely, you can exit the function immediately.

Lab 2a: Debugging Your Application


1. Start Visual Basic. 2. Open the project for the custom application. This file is c:\TGM\Labs\CustomApp\src\CustomApp.vbp. 3. In the Project Window, under the CustomApp (CustomApp.vbp) folder and Forms subfolder, select mfrmMain (mfrmMain.frm) from the Project Window and select View > Code (or double-click on mfrmMain (mfrmMain.frm)). 4. Select the MDIForm_Load method, and set a breakpoint on the line initializing the bInitDataRecordset variable by depressing the function key F9 or through Debug > Toggle Breakpoint. You can also click the mouse in the gray column to the left of the code window. 5. Select the mnuFileOpen_Click method, and set a breakpoint on the OpenDatabase subroutine call. 6. Start your application by selecting the Start button > Start command. The debug window -- Immediate -- will appear. 7. The program will stop immediately in the form load subroutine. 8. Step over the initialization statements, either by depressing the function key F8 or through Debug > Step Into, and select Start before you reach the end of the MDIForm_Load method. or the Run

Creating a Custom Application 59 9. Select File > Open. The program will stop again at the call to OpenDatabase. Step into the OpenDatabase subroutine. 10. Step over the statements (using SHIFT+F8 or Debug > Step Over) until you are positioned at the conditional test for the value of strFile. You will need to select a warehouse before you can get to this comparison. 11. In the Debug Window, key in: print strFile. The debugger will display the current value of strFile. You can also hold your cursor over the variable name. A little tooltip box will appear containing the value. . 12. Select Start to continue execution of the command. 13. Stop the debug session by selecting the stop button or Run > End from the menu. Exit Visual Basic. Summary: This section showed you how to establish the debug environment for your application and some of the basic operations available for debugging.

Lab 2b: Application Framework and Connecting


In this lab, you will be writing the code behind the File > Open, File > Close, and File > Exit commands on the menu bar in the custom application. Remember that this application will be modified in all of the remaining labs. File > Open will make a connection to an Access database. File > Close will close the chosen connection. File > Exit will clean up references and exit the application. Note: Before you can use GeoMedia objects in a custom application, you need to add its Program directory to your path. You should do this on your lab machines by selecting Start > Settings > Control Panel on the Windows NT task bar. Now choose System. From the Environment tab, select Path in the System Variables: list. You should now see Path in the Variable: text box near the bottom of the dialog and your existing path in the Value: text box. Place your cursor in the Value: text box and go to the end of that path. Type in the following value, substituting your appropriate drive and directory structure: ;C:\Program Files\GeoMedia\Program Do not place any quotes around this value. Now choose the Set button, and select OK to dismiss the dialog. You will need to reboot your system to ensure that the new value has taken effect.

60 Fundamentals of GeoMedia Development Part I 1. Open the Visual Basic project C:\TGM\Labs\CustomApp\src\CustomApp.vbp. In the Project Window, under the Modules folder, select modDatabase, and select View > Code. 2. In Sub OpenDatabase, create a Connection by calling the Add method on the global Connections object already created for you gobjConnections. This is the function called when you select File > Open. Dont forget that object variables need to be Set in Visual Basic. The argument to the Add method is the value of the local variable strFile. The global variable, gobjConnections, is declared in modGlobals.bas. 3. Make the actual connection (open the database) by setting the Type and Location properties of your new connection, and by calling its Connect method. The Type property needs to be set to the same string as the ProgID argument would be if you were creating a GDatabase objectin this case Access.GDatabase. The Location property is the path to the actual warehouse file, in this case the .mdb. This is the string returned by the BrowseForFile function already in your project (it gets it from the Common File Open dialog). When youre finished making the connection call the Connect method. 4. In Sub CloseDatabase, populate the lstDatabases List box on frmDatabase with each of the open connections. The loop processes every connection in the collection by looking at the Count property. You only want to put open connections in the list, so you will look at the value of the Status property on the Connection object. When you find an open connection, add the name of the connection (ConnectionName) to the listbox. You may close the code window when you have completed this step. Note: All of the forms controls have been named such that the prefix indicates the type of control. For example, lstSomething is a listbox, txtValue is a textbox, and cboChoices is a combobox. 5. In the Project Window, under the Forms folder, select frmDatabase, and select View > Code. 6. In Sub btnOK_Click, find the connection the user has chosen in the Connections collection and close it. You can iterate over each of the connections in the gobjConnections collection. Determine if it is the one the user has chosen by comparing its ConnectionName property with the item in the list box the user chose. Close it by calling the Disconnect method on the connection object. You can close the code view window for frmDatabase.

Creating a Custom Application 61 7. In the Project Window, under the Forms folder, select mfrmMain, and select View > Code. 8. In Sub MDIForm_Unload, close any open connections, and release the global pointer to the Connections collectiongobjConnections. You will need to reference the global collection (gobjConnections) and then call the Disconnect method on each item in the collection. To release an object variable, set it to Nothing. 9. Now, test your code by running the application, and exercise File > Open, File > Close, and File > Exit from the Main Window. Choose the Start command from the toolbar or Run menu. In your applications main window, main menubar, select File > Open. In the Common File Open dialog, choose an Access database (e.g., US Sample Data.mdb in the Warehouses directory). Select File > Close, and choose the connection you just opened. Try having multiple connections open and having more than one to choose from when you close. Select File > Exit. Summary: In Lab 2, you have created a connection object, added it to the applications collection, and connected to the database. Also, in implementing the close command, you have disconnected from the database. Although we dont set the Mode property, you will need to do this for read-only connections. Use the constant gmcModeReadOnly for the value. You have also practiced debugging your application

62 Fundamentals of GeoMedia Development Part I

Creating and Manipulating Recordsets


Once you have connected to a warehouse or database, the primary object you will be using to manage the data is a GRecordset (often just called recordset). You can create a recordset in one of two ways. The first is simply by calling the OpenRecordset method on a GDatabase object. The second is by creating an OriginatingPipe. A recordset is a data structure containing graphic and attribute data. It is analogous to a database cursor. The recordset is important within GeoMedia as it is the common data unit for communication between software components.

Creating a Recordset with OpenRecordset


Given a GDatabase object either one created independently or through the Connection object, you can call OpenRecordset to create a recordset. For example: Dim objRS As GRecordset Set objRS = objAccessDbs.OpenRecordset (Parcels) This will populate objRS with a GRecordset containing all the parcels in your database with each parcel represented as a row or record in the recordset. Just supplying a GTableDef name (e.g., Parcels) is the equivalent of passing an SQL select statement to select all members of the given GTableDef. Therefore, the above statement is equivalent to: Set objRS = objAccessDbs.OpenRecordset (SELECT * FROM Parcels) You can further refine the results with attribute query criteria, as in: Set objRS = objAccessDbs.OpenRecordset (SELECT * FROM Parcels WHERE AssessedValue > 100000) Additionally, you can apply a spatial criteria for filtering by using other optional arguments to the OpenRecordset method. There are several additional optional arguments to OpenRecordset. This discussion will address one of those. The second argument to OpenRecordset is optional and determines the type of Recordset created. By default (i.e., if the second argument is not specified), a Dynaset recordset is created (or by supplying gdbOpenDynaset as this second argument). The other type is a Snapshot recordset, created by supplying gdbSnapshot as the second argument. A dynaset recordset is updateable (if your connection and GDO server are read/write) and is a dynamic view of your data. In other words, the actual field values are gathered from the GDO server on demand, so that you will always get the latest data. This is powerful, but can be slower especially if the data is coming across a network connection.

Creating a Custom Application 63 A snapshot recordset is a static copy of the data generated at the time you called OpenRecordset. Its a picture or view of the data at the time you generated the recordsetits not aware of changes made to that data after you created the recordset. You cannot add, delete, or edit its records. But, a snapshot is more performant if the dynamic or updateable aspects of a dynaset are not needed.

Creating a Recordset with OriginatingPipe


As alluded to earlier, the second method for creating a recordset uses an OriginatingPipe. In essence, the same information is provided to the OriginatingPipe object via its properties as is provided to the OpenRecordset method via its arguments. In fact, the OriginatingPipe creates its output recordset by calling OpenRecordset. Then why have a second way of creating a recordset? Pipes add additional functionality to recordsets including the following. Persistence Notification Metadata access Recordset naming Errors CoordSystem

These additions add significant power to your GeoMedia applications. Except for persistence, all of these additions are available in custom applications. You create an OriginatingPipe using the CreateOriginatingPipe method on a Connection. Once created, supply it with the necessary properties as criteria for the particular data you want, then reference the OutputRecordset as you would any other recordset. Dim objOP As OriginatingPipe gobjConnections(1).CreateOriginatingPipe objOP objOP.Table = Parcels objOP.Filter = AssessedValue > 100000 Dim objRS As GRecordset Set objRS = objOP.OutputRecordset

Manipulating Records in a Recordset


In the next section, you will learn how to display a recordset on a map, and how to display its attributes in a DataView. But, how do you work with the records (rows) and fields (columns) of a recordset individually? As mentioned earlier, set notation differs from collection notation. You

64 Fundamentals of GeoMedia Development Part I iterate over a recordset using the move methods (Move, MoveFirst, MoveLast, MoveNext, and MovePrevious), such that you always have a current record (pointed to by the Bookmark property). You then can iterate over the fields of that record (or jump to a particular field) via the recordsets GFields collection. For example, given a recordset, you typically can access each and every record with code similar to the following: Set objRS = objDB.OpenRecordset (Parcels) If Not (objRS.EOF and objRS.BOF) Then Do Until objRS.EOF .

code processing the individual records


. objRS.MoveNext Loop Else MsgBox (No Parcels found.) End If Note: In the above code, you are checking for a non-empty recordset by ensuring that its EOF and BOF are not both True. The recordset also has a RecordCount property. The RecordCount will be greater than 0 when the recordset is first opened as long as there is at least one record. This property will return 0 had there been no records satisfying the query. However, the property cannot be depended upon to return the total number of records in a non-empty recordset until either the loop above finishes processing (i.e., youve done a MoveNext through every record) or a MoveLast has been issued on the recordset. Both are expensive operations just to get the record count, and should not be issued unless the exact count is needed. Otherwise, you can use this property like a boolean property telling you whether the recordset is empty (value of 0) or not (some other value). Or, accomplish the same test by checking to see if both the BOF and EOF properties are True, in which case the recordset is empty. The BOF property is set to True when the recordset is empty or when youve done a MovePrevious beyond the first record. EOF is set to True when the recordset is empty or when youve done a MoveNext beyond the last record.

Creating a Custom Application 65

IMPORTANT: A common mistake is to forget to put the MoveNext in a loop similar to the one above. In this case youve created an infinite loop. You can process the fields as you would any other collection using a For loop if you want to iterate over all of them. For example, in the code above, you might want to iterate over each of the fields. Inside the loop, add code as follows: Dim objField As GField For Each objField in objRS.GFields Print #1, objField.Name & : & CStr(objField.Value) Next objField Note: If this code is inside the recordset loop in the previous example, objRS will successively point to each record or row in the recordset.

Geometry Formats
How does the GDO server expose the geometry of the features being returned? In the same way it exposes all the other attributes of the feature as a GField object. Each GField object has a Type property. A geometry field will have a Type of gdbSpatial or gdbGraphic. If the Type of the field is gdbSpatial or gdbGraphic, then it will also have a SubType property that further defines the geometry type. Valid values for SubType in GeoMedia are shown relative to the geometry types. Type / SubType gdbSpatial Description Classification of data such that the coordinate information is assumed spatially accurate Geometry which is comprised of a series of points Geometry which is comprised of a series of points where the first and last point are coincident. The area may include one or more holes. Geometry which might either contain one of each type of geometry (gdbPoint, gdbLinear, gdbAreal) in a collection or might contain any one of these types in a given feature class Geometry describing an image (raster

gdbLinear gdbAreal

gdbAnySpatial

gdbCoverage

66 Fundamentals of GeoMedia Development Part I data) gdbPoint gdbGraphic Geometry defined by a single point Classification of data such that while coordinate information is identified relative to the earth, the spatial location is not significant. This type is usually associated with annotative data like labels. Same as in gdbSpatial. Same as in gdbSpatial. Same as in gdbSpatial. Same as in gdbSpatial. Same as in gdbSpatial. Geometry defined by a point and a text string. Same as in gdbSpatial.

gdbSpatial gdbLinear gdbAreal gdbAnySpatial gdbCoverage gdbGraphicsText gdbPoint

The values for the geometry fields are exposed in a binary format often called a BLOB (Binary Large OBject). This format is documented on the Team GeoMedia web site in the Technical White Paper Geometry Specifications. The values for these geometry fields are not exposed as Geometry objects. The GeometryStorageService object provides methods for converting from this storage format to a Geometry object and vice-versa. When writing applications that need to read or write these values external to GDO, it is recommended that you use the Geometry object to abstract your program from the binary format. This will make your program less vulnerable to needing modification should these formats change in the future.

Lab 3: Creating a Recordset


In this lab, you will be writing the code behind Analyze > Recordset Information. You will complete the code in a sub procedure (CreateRecordset) that will display a dialog to the user of all connections he has open and all valid tables for him to select from each of those connections. Given his selection, you will then complete the code in another sub procedure (AnalyzeRecordset) to take that table and display some analysis of the recordset generated on that table. 1. Open the Visual Basic project C:\TGM\Labs\CustomApp\src\CustomApp.vbp. In the Project Window, under the Forms folder, select frmSelectFeature, and

Creating a Custom Application 67 select View > Code. 2. In Sub cboDatabases_Click, get the list of all tables in the active connection and populate the lstFeatures list box with those tables. You could accomplish this by populating the list box with each of the GTableDef.Name values. This would, however, return even the non-displayable (i.e., metadata) tables. Therefore, it is better to create a MetadataService (objMDSrvc) and use its GetTables method to get only displayable tables. The returned data is stored in vTableList. The data type is Variant which simply means any data type may be stored in this argument. In this case, an array of strings is returned. The Visual Basic built in functions, UBound and LBound, return the upper and lower bounds of the array dimension. 3. In the Project Window, under the Modules folder, select modRecordset, and select View > Code. In Sub CreateRecordset, create a recordset using an OriginatingPipe. The recordset will be based on the feature the user selected. Create an OriginatingPipe by calling CreateOriginatingPipe on the connection returned from GetSelectFeatureInfo. This is store in the variable objActiveConnection. Set its Table property to the table name returned from GetSelectFeatureInfo. Assign the OutputRecordset of the OriginatingPipe to the output argument of CreateRecordset (objRS). The CreateRecordset sub procedure is used in multiple places throughout this application. You will also see that this subroutine creates the transformation object for the data that will be displayed from this recordset. This operation is discussed in subsequent exercises. 4. In Sub AnalyzeRecordset, call CreateRecordset to have the user create a new recordset. This is the sub procedure called when you select Analyze > Recordset Information Recall that a subroutine calling statement does not require parenthesis around the arguments. ObjRS is the argument to CreateRecordset. 5. Display the name of the feature on frmRecordsetInfo in the txtFeature Text box. Use the value of SourceTable on one of the recordsets fields. 6. For each field in the recordset, display its name in the lstFields List box, and tally (keep a running count) each of the types of fields. You will iterate over the GFields collection. You will examine the Type property on the GField object (objField). Dont forget to release objField after completing the loop. 7. Display the count of records in the recordset in the txtCount Text

68 Fundamentals of GeoMedia Development Part I box. In order to get the correct count of records (rows), you must go to the last row. However, it is invalid to do this if there are no rows. First check the EOF and BOF properties on the recordset (objRS). 8. Now, test your code by running the application, and selecting Analyze > Recordset Information from the Main Window after you have opened a connection. Choose the Start command from the toolbar or Run menu. In your applications main window, main menubar, select File > Open. In the Common File Open dialog, choose an Access database (e.g., US Sample Data.mdb in the Warehouses directory). Select Analyze > Recordset Information, and choose a feature to analyze. Summary: In Lab 3, you used the MetadataService to retrieve the list of features available in the warehouse. You created a recordset with the OriginatingPipe. Finally, you accessed the fields within the recordsets fields collection and you accessed the count of records (rows) within the output recordset. Each row is equivalent to a feature instance.

Creating a Custom Application 69

Adding a MapView and Displaying Data


The main distinction between a GRecordset from GDO and a Recordset from DAO is that the GRecordset data is geographic in nature. In other words, geometry and world coordinate information are served up such that the data has spatial context. This context has little meaning without viewing that data spatially or on a map. The MapView OCX supplied with GeoMedia gives you that context. The MapView OCX is the custom control on which you will display the spatial aspect of your GRecordset. During the next lab exercise, you will learn the mechanics of adding a MapView to your application. Additionally, the MapView gives you view manipulation functionality (e.g., zooming, fitting, etc.) as well as giving you the extensions for selecting and highlighting elements, coordinates systems management, and the legend.

MapView Legend LegendEntries CoordSystemsMgr


The Legend is the mechanism by which you will actually display the data on the MapView. The Legend is a member object of the MapView. In a custom application, you will need to create it and assign the MapViews Legend property to the one you created, as in: Dim objLegend As New Legend Set ocxMapView.Legend = objLegend Set objLegend = Nothing LegendEntries is a heterogeneous collection on the Legend that stores information on each logical grouping of data displayed on the map. For our purposes, you will be creating a RecordLegendEntry. Displaying data on a map is as simple as creating a recordset, creating a style object to set the data display characteristics, both of which are input into creating a RecordLegendEntry, and appending that to the Legend.

Coordinate Systems and Transformations


There is one other aspect of displaying data in a map view which you will need to ensure is properly handled. This involves coordinate systems and transformations between your data and the map view in which you are displaying that data. Every connection will have one or more coordinate systems (server side). Each map view will have a single coordinate system (client side). If you know that all of your data is in

70 Fundamentals of GeoMedia Development Part I the same coordinate system and you want it displayed in the same coordinate system, then you can set the coordinate system on your map view to be the same as that of your data and you will not need to be concerned about transformations. However, in most cases you will want to approach the problem with a more generic solution. GeoMedia provides the tools for you to easily accomplish this such that your data may exist in one or more coordinate systems that are entirely different from the one in which you are displaying the data. Once the transformations are properly configured, GeoMedia will do on-the-fly transformation of your data to the proper coordinate system of the map view. The two objects you will use to accomplish this are the ServerTransService and the CSSTransformPipe. In a custom application, you will need to create and define the CoordSystemsMgr and CoordSystem for your map view. If you dont explicitly define the coordinate system, GeoMedia will create a default one for you, just by issuing a CreateObject on the CoordSystemsMgr, as in: ocxMapView.CoordSystemsMgr = CreateObject _ (CoordSystemsMgr) Then, to ensure that the data you are displaying in that map view is transformed properly, create a ServerTransService, and define a transformation between your server and map view by calling the CreateSimpleTransFromCSMtoServer method. Then, pass each recordset you wish to display through a CSSTransformPipe before assigning it to a legend entrys recordset and calling LoadData. This will transform all the geometries of the recordset such that they will be displayed properly on the map view. There is an example of this in the CreateRecordset function of modRecordset in the previous lab exercise. Figure 0-1 Recordset in CS A Recordset in CS B Transform from A to X Transform from B to X

MapView in CS X

The reverse is true, as well. If your application allows the user to digitize some data, you will need to transform it from the map view coordinate system back to the servers coordinate system before you write it to the data store.

Creating a Custom Application 71

Lab 4: Constructing the MapView


In this lab, you will complete the code necessary to display data on a mapview the code behind selecting View > Add Feature in your application. You will begin by placing the MapView on a form. You will create the default coordinate system and a legend on the MapView. You will write code controlling the display of the legend. Then, you will complete the code necessary for creating a legend entry and displaying that legend entry on the MapView. 1. Open the Visual Basic project C:\TGM\Labs\CustomApp\src\CustomApp.vbp. In the Project Window, under the Forms folder, select frmMap, and select View > Object. The form will be opened, and it will contain the Map Window. 2. Delete the existing MapView control by selecting this control on the form and pressing the delete key. (The control already existed in the lab project so that other code referencing it would compile.) Remove the MapView as one of the controls on the toolbox by selecting Project > Components In the Components dialog on the Controls tab, uncheck GMMapview OLE Custom Control module, and select OK to dismiss the dialog. You should see one of the buttons on your toolbox whose ToolTip reads GMMapView disappear. Now add the MapView back as one of the controls on the toolbox by selecting Project > Components In the Components dialog on the Controls tab, check Intergraph GeoMedia Mapview Control 2.0, and select OK to dismiss the dialog. You should see a new button on your toolbox GMMapView. whose ToolTip reads

This reference had to exist in your lab project so that references to this GMMapView would compile. The purpose of your removing it and replacing it on the toolbox was so that you would understand how GeoMedia controls are added to the toolbox in your Visual Basic project. 3. Select the GMMapView control on the toolbox by clicking on the button whose tooltip reads GMMapView. Now when you move your mouse you will be in control placement mode. On the Map Window of frmMap, click (and hold) the left mouse button with your mouse pointer on the upper-left-most gridmark in the Map Window. Drag to the lower-right-most gridmark, and release the mouse button to complete the placement of the MapView on the

72 Fundamentals of GeoMedia Development Part I form. You should see a blank MapView on the Map Window. 4. Name the GMMapView control ocxMapView. Make sure the upper left coordinates of the MapView are 0, 0. In the Properties window, modify the Name, Top, and Left properties of the GMMapView. If the GMMapView is not already the active control, you can make it the active control by either selecting on it in the Form, or by selecting it from the Properties Window Control pull-down. 5. In the Project Window, under the Forms folder, select frmMap, and select View > Code. In Sub Form_Load, create a CoordSystemsMgr, and set the NominalMapScaleDenominator of the CoordSystem.RefSpaceMgr.PaperSpace member object in the CoordSystemsMgr. Then, assign the CoordSystemsMgr object to that property of the ocxMapView. This will create a default CoordSystem as a member property of the CoordSystemsMgr, giving your map view a Cylindrical Equirectangular projection and other default coordinate system parameters that will serve our purposes well in displaying data and demonstrating on-the-fly transformation from the coordinate system parameters of your data server or data store. 6. In Sub Form_Load, create a Legend and assign it to that property of the map view. The ProgID for all GeoMedia objects are listed in the Appendix. The newly created Legend object must be assigned to the Legend property of the ocxMapView. 7. In Sub mnuViewLegend_Click, toggle the display of the Legend on and off. For displaying the Legend, there is a Visible property whose type is boolean. Since you are toggling the display, if the legend is currently displayed (Visible = True), then turn it off. For controlling the check mark on the menu, use the Checked property. MnuViewLegend is the menu item for the Legend Toggle command. 8. Now, test the code youve written thus far by running the application, and selecting View > Legend from the Main Window after you have activated the Map Window. Choose the Start command from the toolbar or Run menu. In your applications main window, main menubar, select Window > Activate Map. Select View > Legend, and the Legend should appear in your map view. Note that it is empty as we have not added any legend entries yet. Select View > Legend again, and you should see the legend disappear. You may quit the application by selecting File > Exit.

Creating a Custom Application 73

Note: In Sub mnuDisplayFeature_Click, notice the structure of the code already in place for displaying a feature on the map. You are calling CreateRecordset from the previous lab. Once youve created a recordset, it is used as input to the function GetLegendEntry. Given the RecordLegendEntry returned from that function, you call DisplayTheLegendEntry to actually display the data on your map view. In the next steps, you will be writing code that provides the key functionality for those two procedures. You can close the code and object windows of frmMap. 9. In the Project Window, under the Modules folder, select modMap, and select View > Code. Create the RecordLegendEntry that will be returned by this function. By assigning a value to the name of the function, you are setting the return type from the function. 10. Notice how you can get additional information about the recordset using the ExtendedPropertySet object since the recordset was created with OriginatingPipe. This functionality is used to get the PrimaryGeometryFieldName. Now similarly, get the recordsets Name property from the extension object and assign its value as the legend entrys title. Remember the GetLegendEntry is a variable of type RecordLegendEntry. The extended property set object is stored in the objExt variable. The value of the Name will be used as the legend entrys Title. Note: Similarly, the extended property GeometryType is used to get the geometry type which is passed to the function GetStyleObject. This function returns a style (based on the given geometry type) that is then assigned as the Style property of the RecordLegendEntry. Style objects will be covered in more detail in a later lab. This function will abstract that for us during this lab. 11. As we have discussed, a transformation must be established between each coordinate system used by your application. In the CreateRecordset procedure, the ServerTransService is created to create a transformation between the projection of the coordinate system of the map view and the data being returned from the server. This one method call is all that is needed to accomplish this. Now that the transformation has been created, a CSSTransformPipe is created to take the input recordset and give an output recordset whose geometries have been transformed from the server side to the client side. Take that output recordset from the pipe object and assign it to the legend entrys Recordset property. Using the Set keyword, assign the OutputRecordset from the

74 Fundamentals of GeoMedia Development Part I objCSSPipe to the GetLegendEntry variable. 12. In Sub DisplayTheLegendEntry, the legend entry is checked to be sure it is a valid object, and then ValidateSource is called to ensure that it has a recordset and proper geometry field set. Append the legend entry to the legends LegendEntries collection, and load the data by calling the LoadData method on the legend entry. If it is the first legend entry being loaded on the map view, then do a fit of the data in the map view. The Append method has a first argument of a legend entry and then two optional argumentsBeforeIndex and AfterIndex. It must be called without an index when appending the first Legend Entry. The second and subsequent times Append is called requires using either the BeforeIndex or the AfterIndex argument, but not both. For this exercise, append the second and subsequent legend entries to the top of the legend (i.e., give them a BeforeIndex of 1). The legend entry to append is stored in objLE. If this is the first legend entry, we want to call Fit on the map view. 13. Now, test your code by running the application, and selecting View > Add Feature from the Main Window after you have opened a connection and activated the Map Window. Choose the Start command from the toolbar or Run menu. In your applications main window, main menubar, select File > Open. In the Common File Open dialog, choose an Access database (e.g., US Sample Data.mdb in the Warehouses directory). Select Window > Activate Map. Select View > Add Feature, and choose a feature to display. Notice that if you view the legend now (View > Legend), you will see the newly created legend entry. Summary: In Lab 4, you have placed a map view control on your form. The paper scale of the coordinate system has been adjusted to control the thickness of the lines in the display. The legend entry was created this involved finding the geometry field using ExtendedPropertySet, creating a default style, and appending the entry to the collection. A coordinate transformation was established between the server and the views coordinate system. Finally, the legend entry was validated and the data loaded into the geometry cache.

Creating a Custom Application 75

What are Styles?


A style is an object that describes how to visualize the geographic data. Typically, the style includes color and weight. A style object is assigned to each legend entry. You can use the same style object on multiple legend entries. The simplest approach to defining a style is to create a linear style object. You can apply this object to any geometry type. The drawing process will then use whatever information that is in the style object that it can, and apply it to the current geometry. As such, if the geometry is areal, only the edges will display. There will be no associated filling of the area. If the geometry is point, only a dot will appear. There is also an AnyStyle object which has member object properties for each possible style type. This is most often used for the gdbAnySpatial geometry type. The display process attempts to use the best fit most appropriate style for the geometry type. In the linear and area styles, you have both a back and fore color and back and fore width settings. This allows you to draw two lines for each geometry. This enables more variation in symbolization. The Color and Width properties are equivalent to setting the BackColor and BackWidth properties. GeoMedia supports the display of point objects with true type fonts as well as MicroStation symbol font resources. You must define the appropriate registry keys for the location of your resource files. All files present in the directories will be available for use. GeoMedia recognizes three keys which specify directories that contain resource files: HKEY_CURRENT_USER\Software\Intergraph\Applications\GeoMedia \PrefSets\Options-FileLocations\Font1, ...\Font2, and ...\Font3. The keys value must be the full directory path. The directories need not be part of the GeoMedia installation directory. GeoMedia also supports a bitmap style. Additionally, a symbol element may be created from MicroStation cell libraries or from AutoCAD block files. Use the Define Symbol File utility to create the .FSM file. GeoMedia also provides style objects for patterned lines and areas. You can combine the symbol element and the line or area styles to create a pattern. In the GeoMedia user interface, style widths are assigned based on points a standard printers measurement. Use the following values to determine how to calculate the desired point sizes. Remember, the style width is based on the paper scale of the coordinate system. If your display is greater or smaller than the paper scale, the measurements will not match point size you specified. One point is 1/72 of an inch (0.0139 inches)

76 Fundamentals of GeoMedia Development Part I One point is 0.353 millimeters When using gmsStyleUnitsPaper, the Width is specified in HIMETRIC units where 100 units is one millimeter (one unit is 0.01 millimeters) Using the HIMETRIC measurement, 35 units is one point (1/3 of a millimeter)

For example, if you specify 300 units in the Width property, the GeoMedia style dialog will display 9 points. At your defined paper scale, the line will measure 3 mm or 1/8 inches. If you specify the StyleUnits property as gmsStyleUnitsView, you are indicating that the width reflects the number of pixels to use. Finally, the StyleUnits property of gmsStyleUnitsPaperAsNonscaling is calculated like the gmsStyleUnitsPaper setting, but behaves like the gmsStyleUnitsView. This option is referred to as View Independent. That is, the width of the style is calculated from the point or HIMETRIC input, but is a width relative to the screen rather than the ground or geographic space. Hence, 36 point text would appear as inch on the screen. Additionally, the width will remain at inch no matter what the view extents. This is contrary to gmsStyleUnitsPaper which gets smaller as you zoom out and larger as you zoom in.

OPTIONAL Lab 5: Creating Specific Style Objects


In this lab, we will expand our legend entry subroutine to assign the style based on the geometry type.

Style Object AreaStyle AnyStyle BitmapStyle HandleStyle LinearStyle SymbolFontStyle TextStyle PointSymbolStyle PatternedLinearStyle PatternedAreaStyle

Normally Applied To Subtype = gdbAreal Subtype = gdbAnySpatial Subtype = gdbPoint Not applicable Subtype = gdbLinear Subtype = gdbPoint Subtype = gdbGraphicsText Subtype = gdbPoint Subtype = gdbLinear Subtype = gdbAreal

Covered in Lab? Yes Yes No No No Yes Yes No No No

Creating a Custom Application 77 In this first section, you will add logic to support gdbPoint and gdbGraphicsText subtypes for the geometry data. For all style objects, you will set the StyleUnits to gmsStyleUnitsPaper. For the Color properties, employ a cyclic assignment of color values. Use the QBColor function to convert the nNextColor index value to the RGB value.

Section A: Adding Symbols and Text


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select modMap from the Modules list, and select View > Code. 3. Select the (General) object, and select the GetStyleObject procedure. 4. Add a case statement for point type geometry. You will need to create the SymbolFontStyle object and populate it appropriately. First, create the object with the GeoMedia.SymbolFontStyle ProgID. Then populate the minimum set of properties: Color, StyleUnits, FontName, Index, and Size. Setting the Color and StyleUnits properties are described in the lab introduction. The FontName is either the name of a true type font or a MicroStation symbol font. The Index is the position in the list of glyphs within a font. This is usually a value between 0 and 255, but will vary by particular font. For this exercise, use Wingdings for the FontName and a number between 33 and 200 for the Index. Finally, the Size or width should be set to 300 for a 3 mm size as described in the section overview. 5. Add a case statement for gdbGraphic geometry. Because you know the metadata techniques used to retrieve the element type, you know that this geometry type represents gdbGraphicsText elements. You will need to create the TextStyle object and populate it appropriately. First, create the object with the GeoMedia.TextStyle ProgID. Then populate the minimum set of properties: Color, StyleUnits, and Font. Setting the Color and StyleUnits properties are described in the lab introduction. The Font is a Microsoft StdFont object. Create a new StdFont object and assign it to the Font property. Within the StdFont object, you must set the Name and Size properties. Name is the name of the text style like Arial or Times New Roman. Size is the number of points to display the text at. There are other properties you may set like Bold. 6. Save the project, and compile the executable by selecting File > Make customapp.exe. 7. Test the application. Open a database. Select Window > Activate Map. Select View > Add

78 Fundamentals of GeoMedia Development Part I Feature, select the Cities feature and select OK. The city points should appear in the style you created. Select View > Add Feature, select the StateNameLabels feature and select OK. The state names should appear in the style you created. You may need to adjust the point sizes for correct sizing. Summary: In Lab 5, Section A, you defined symbol font and text styles. This included manipulating the StdFont object.

We can now expand the styles to include gdbAreal and gdbAnySpatial. To display the compound geometry, you will need to connect to the AnySpatial.mdb database.

Section B: Adding Area and AnyStyle


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select modMap from the Modules list, and select View > Code. 3. Select the (General) object, and select the GetStyleObject procedure. 4. Add a case statement for gdbAreal geometry. You will need to create the AreaStyle object and populate it appropriately. First, create the object with the GeoMedia.AreaStyle ProgID. Then populate the properties. This style object is divided into two parts. The member object Boundary defines the style of the line bounding the area. This object is created by default and is a read-only property. Set the properties of this object as shown in the case for gdbLinear. The remaining properties describe the characteristics of the inside of the area (fill). BackColor is the color for the filled area. FillMode should be set to gmsFillModeStandard. Select any of the gmsFP constant values for the FillType property. This describes the hatching pattern to use in the fill area. StyleUnits is populated as described in the other sections of the lab. ForeColor is the color of the hatching. HatchSpacing is the number of pixels between hatch lines in the fill pattern. HatchWidth is the number of pixels for the width of the hatch lines. 5. Add a case statement for gdbAnySpatial geometry. You will need to create the AnyStyle object and populate it appropriately. This object simply has member properties which are the simple style types that we have already created. You need only create this object and create one of each of the dependent objects: TextStyle, SymbolFontStyle (for the PointStyle property), LinearStyle, and AreaStyle. First, create the object with the GeoMedia.AnyStyle ProgID. Then create the simple style objects. You can simply copy the code we

Creating a Custom Application 79 used in the other steps for this exercise. You may want to adjust some of the simple style properties to help differentiate the display. Then populate the properties of the AnyStyle object with these simple style objects. 6. Save the project, and compile the executable by selecting File > Make customapp.exe. 7. Test the application. Open a database. Select Window > Activate Map. Select View > Add Feature, select the States feature, and select OK. The states should appear in the style you created. Open another database AnySpatial.mdb in c:\TGM\Labs\CustomApp. Select View > Add Feature, select the CityFacilities feature, and select OK. A few AnySpatial features will appear in the style you created. You may need to adjust the point sizes for correct sizing. The CityFacilities are in the vicinity of Chicago, Illinois. Summary: In Lab 5, Section B, you defined the area style. This completes the primitive style types (excluding BitmapStyle and PointSymbolStyle). You also defined the AnyStyle object which contains member objects for each of the primitive types.

80 Fundamentals of GeoMedia Development Part I

What is Marginalia?
Marginalia is a term used to describe graphics that typically appear in the margin of a printed map. In GeoMedia, there are currently two of these types of objects: NorthArrow and ScaleBar. The NorthArrow indicates the direction of the geographic north pole relative to the data. The NorthArrow is a custom control that can be placed on your form. You must set the MapViewID property of the control to the map views Dispatch property. This allows the control to retrieve the coordinate system information to determine the direction of north. The ScaleBar reflects the scale of the map. That is, when you use a ruler to measure distances on the map, the scale indicates how much ground is covered. For example, one inch measured on the paper may represent 100 feet or 100 miles depending on your scale. Like the NorthArrow, the ScaleBar is a custom control that can be placed on your form. The ScaleBar also requires that its MapViewID property be set to the associated map views Dispatch property. This allows the control to retrieve the coordinate system information to determine the current scale of the view.

OPTIONAL Lab 6: Marginalia


In this lab, we will add the custom controls to our map view. We will set the necessary properties in the form load operation and turn on their display.

Section A: North Arrow


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmMap from the Forms list, and select View > Object. The Map Window form will appear. 3. Delete the existing GMNorthArrow control by selecting this control on the form and pressing the delete key. From the toolbox, select the GMNorthArrow control. The cursor will change to cross or plus sign. 4. Create a rectangle by placing the cursor in the upper right corner of the form and dragging to create a 495 x 495 box. An arrow bitmap will appear. The name of the control will default to GMNorthArrow1. 5. Adjust the properties of the control to set BackTransparent to True in the Properties Window. This only applies to the printed north arrow and not to the display.

Creating a Custom Application 81 6. Set the BackColor to the color of your map view. Select the Palette tab in the Properties Window to associate a particular color. 7. Select frmMap from the Forms list, and select View > Code. 8. Select the Form object and Load from the procedure list. Add logic to assign the Dispatch pointer of the map view control to the MapViewID property of the north arrow. Both the GMNorthArrow1 and ocxMapView are properties of frmMap. The code skeleton includes logic for adjusting the controls position within the map view control. 9. Save and compile the application. Test the application. Open a database. Select Window > Activate Map. The NorthArrow should appear at the location you placed the control. The area surrounding the arrow should be the same color as the map view. Summary: In Lab 6, Section A, you placed the control on the form and established the communication through the map view. Many other properties can be configured for the North Arrow.

Section B: Scale Bar


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmMap from the Forms list, and select View > Object. The Map Window form will appear. 3. Delete the existing GMScaleBar control by selecting this control on the form and pressing the delete key. From the toolbox, select the GMScaleBar control. The cursor will change to cross or plus sign. 4. Create a rectangle by placing the cursor in the upper right corner of the form and dragging to create a 3255 x 495 box. A scale bar will appear. The name of the control will default to GMScaleBar1. 5. Adjust the properties of the control to set BackTransparent to True in the Properties Window. This only applies to the printed scale bar and not to the display. 6. Set the BackColor to the color of your map view. Select the Palette tab in the Properties Window to associate a particular

82 Fundamentals of GeoMedia Development Part I color. 7. Select frmMap from the Forms list, and select View > Code. 8. Select the Form object and Load from the procedure list. Add logic to assign the Dispatch pointer of the map view control to the MapViewID property of the scale bar. Both the GMScaleBar1 and ocxMapView are properties of frmMap. The code skeleton includes logic for adjusting the controls position within the map view control. 9. Save and compile the application. Test the application. Open a database. Select Window > Activate Map. Select File > Open to open a database. Select View > Add Feature and display the States feature. The ScaleBar should appear at the location you placed the control. The area surrounding the scale bar should be the same color as the map view. The ScaleBar will adjust to the scale of the data. Summary: In Lab 6, Section B, you placed the control on the form and established the communication through the map view. Many other properties can be configured for the ScaleBar.

Creating a Custom Application 83

Printing Maps
While GeoMedia has numerous commands, it does not provide the capability to have one command call another. However, two commands have been enabled Page Setup and Print for custom applications. These are the only two commands that can be called by custom applications. Printing requires two steps. First, you need to establish the Page Setup information. The GeoMedia command object PageSetup is used for this purpose. This task need only be performed once. If this is not initiated, then defaults for the printer will be used as long as you have created valid PreferenceSet and UnitsOfMeasure objects. These objects are GeoMedia objects that may be used in custom applications. For the second step, you will use the GeoMedia command object Print. This object performs the actual print operation. It is assumed that the work performed by PageSetup is complete, but you can print based on defaults without calling this command.

Postscript Printing
If you have loaded the appropriate printer drivers, you can print your output to a postscript file. From Map Window Page Setup on the Printer tab, select Properties. From Document Properties, select Options... Select Encapsulated Postscript File, and specify the file name.

Limitations
The data view cannot be printed outside of GeoMedia. Both command methods display dialogs and there is no option to hide their display. Currently, the NorthArrow and ScaleBar do not print in custom applications.

Map Layout in Imagineer


GeoMedia also provides a mechanism for creating more formal maps. This is accomplished by linking or embedded views from the GeoMedia workspace onto sheets in Imagineer. Imagineer enables you to create sophisticated borders and include other drawings on a single sheet. Refer to the GeoMedia product documentation for more information on this workflow.

84 Fundamentals of GeoMedia Development Part I

OPTIONAL Lab 7: Printing


For this lab, we will implement the Map > File > Print command for the map view.

Section A: PageSetup
1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmMap from the Forms list, and select View > Code. 3. Select the mnuFilePrint object, and select the Click procedure. 4. Call the PageSetup method on the objPageSetup command object. The calling sequence for this method is: PageSetup( Dispatch, PreferenceSet, ApplicationName, HelpFileName, UOM) as Long where the Dispatch argument is the value of the Dispatch property from the map view control. The PreferenceSet is the object of type PreferenceSet. In your application, this is declared globally. The ApplicationName is the text string used for the print queue entry name. Any value may be used. The HelpFileName is the text string indicating the name of the help file used if the help button is selected on one of the dialogs. Any value may be used Finally, the UOM is an object of type UnitsOfMeasure. The return value is always zero. 1. Save the project, and compile the executable by selecting File > Make customapp.exe. 2. Test the application. Open a database. Select Window > Activate Map. Select View > Add Feature, select a feature, and select OK. Select File > Print. The PageSetup dialog should appear. Select OK or Cancel. Summary: In Lab 7, Section A, you created the preference set object and UnitsOfMeasure objects. These are used by the page setup to determine size of the areas. You configured the command to display this dialog.

Section B: Print
1. Return to the project. 2. Select frmMap from the Forms list, and select View > Code. 3. Select the mnuFilePrint object, and select the Click procedure. 4. Add logic to call the Print method on the print command object. The calling sequence for this method is: Print( Dispatch,

Creating a Custom Application 85 ApplicationName, PreferenceSet, HelpFileName) as Long where Dispatch is the value of the Dispatch property from the map view control. ApplicationName is a text string used for the print queue entry name. Any value may be used. PreferenceSet is an object of type PreferenceSet. Finally, HelpFileName is a text string indicating the name of the help file used if the help button is selected on one of the dialogs. Any value may be used. 5. Save the project, and compile the executable by selecting File > Make customapp.exe 6. Test the application. Open a database. Select Window > Activate Map. Select View > Add Feature, select a feature, and select OK. Select File > Print. The PageSetup dialog should appear. Select OK or Cancel. The Print dialog should appear. Select OK or Cancel. If a printer is available, review your results. Summary: In Lab 7, Section B, you initiated the print dialog. Again, the map view dispatch is used to establish the location of the map view. This component actually drives the print operation.

86 Fundamentals of GeoMedia Development Part I

Creating and Displaying Queries


A GIS user has two primary tasks: choose data to display and manipulate data that is already displayed. In this section and the subsequent lab exercises, you will examine the first task at length. Through GeoMedia automation components, you will select and display data that is spatially related to other data. On a related topic, you will examine GeoMedias buffering functionality bufferzone. Finally, you will look at selection of displayed features from the map view, and subsequent review of the attribute data. You choose data to display either through the selection of a table or the selection of a subset of data from one or more tables. The first is called a feature class. You implemented this in Lab 3. The latter is commonly referred to as a query. Both requests result in the creation of recordsets, but the use of spatial operators in selecting the data subset in the second method allows you to generate an infinitely varied set of results. The ability to perform sophisticated spatial queries is a key distinction in separating GeoMedia from ordinary desktop mapping applications and development platforms. GeoMedia has a comprehensive set of spatial operators for the programmer, including touch, are within distance of, are contained by, entirely contain, are entirely contained by, overlap, meet and are spatially equal. These spatial operators work on points, lines, and areas. For example, the contains operator can find a sewer contained within a parcel. You can also build a pipeline such that you can find sewers contained in parcels contained within a particular county. GeoMedia allows the user to save a spatial or attribute query as a new Query object for display in an existing map view or for future use. It is an important distinction to note that GeoMedia does not store the query results as a static entity, but stores the query statement and submits it dynamically to the GDO server when it is needed. In other words, GeoMedia stores the question and not the answer for queries and reissues the question at the right time so that the answer will never be out of date. Queries can be created programmatically in several different ways. You can use the OpenRecordset method of the current GDatabase object as described in detail in Lab 2. You can also use the OriginatingPipe and/or the SpatialQueryPipe to create a query that uses a spatial filter and generates a recordset as the query results. Previously in the section on Creating and Manipulating a Recordset we learned how to create a recordset using the OriginatingPipe. Building on this example, suppose you now want to find out what land parcels are located directly next to a specific highway. This can be done by prompting the user to select the highway which you want to check for

Creating a Custom Application 87 adjacent land. Execute the following code segment: Dim objOP As OriginatingPipe gobjConnections(1).CreateOriginatingPipe objOP objOP.Table = Parcels objOP.SpatialOperator = gdbTouches Dim vSpatialFilter as Variant vSpatialFilter = objHiwayTbl.GFields(Geometry).Value objOP.SpatialFilter = vSpatialFilter objOP.GeometryFieldName = Geometry Dim objRS As GRecordset Set objRS = objOP.OutputRecordset In this example, the spatial filter is passed into the OriginatingPipe as a geometry blob which GeoMedia uses along with the spatial operator to determine which records satisfy the query criteria. Use of the SpatialQueryPipe to execute a similar query will be explained in detail in the next section. Once the query is created, GeoMedia uses query folders to organize saved queries and for quick recall of previously saved queries. Query folders are a key component in implementing shared recordsets which help eliminate redundant recordsets (i.e., identical queries). Through this organization, GeoMedia minimizes both the number of queries and the amount of time required to execute a query. Refer to Lab 14 for more discussion on the GeoMedia query folder hierarchy. Because queries are simply recordsets the common currency used to communicate between components in GeoMedia, they are displayed in a map view or data view just like we have done with other recordsets. This means that in order to display a query in a map view you will first take the recordset resulting from the query operation, transform it to the current map view coordinate system, assign it to a RecordLegendEntry, add the entry to the legend, and finally execute the ValidateSource and LoadData methods on the legend entry. A query can be displayed in a data view by simply assigning the recordset to a valid data view.

88 Fundamentals of GeoMedia Development Part I

Spatial Query Pipe


As we discussed briefly in the introductory section, a pipe is a software component that accepts one or more recordsets as input and produces a new recordset based on some analysis. The spatial query pipe performs a spatial (geographic) analysis of the data from the input recordsets. The resulting recordset will contain one of the following. Data from the first recordset that meets the spatial criteria Data from the second recordset that meets the spatial criteria The derived geometry resulting from the spatial comparison A combination of data from one of the recordsets and the derived geometry

Spatial Operators
The pipe supports several different spatial operators that control the analysis. These are described pictorially here. In all cases, the spatial analysis iterates over each record in the first recordset comparing it to every record in the second recordset.

Diagram conventions
point line area

The gmsqWithinDistance operator will find all features in the first recordset which contain at least one point within the specified distance of the current record in the second recordset.

Creating a Custom Application 89

gmsqWithinDistance -- are within distance of


20 meter zone 2 3 1 1 2 2 point 2 is within 20 meters of point 1 point 3 is not within 20 meters of point 1 point 1 and line 2 are within 1.5 miles of line point 2 and line 3 are not within 1.5 miles of line 1.5 mile zone 1 3

15 yard zone 2 1

Note that: there is only one area, and it has a hole point 1and line 3 are in the areas hole the zone has a hole point 1 is also in the zones hole point 2, line 1, and line 3 are within 15 yards of the point 1 and line 2 are not within 15 yards of the

2 1 3

The gmsqMeet operator will find all features in the first recordset which share a single point with the geometry of features in the second recordset.

gmsqMeet -- meet
1 2

line meets point point meets line

line 1 meets line 2 area meets point line 2 meets line 1 point meets area

line meets area area meets line

area meets area

The gmsqOverlap operator will find all features in the first recordset which share some portion of geometry with features in the second recordset.

90 Fundamentals of GeoMedia Development Part I

gmsqOverlap -- overlap

line overlaps point point overlaps line

line overlaps line

area overlaps point point overlaps area

line overlaps area area overlaps line

area overlaps area

The gmsqContains operator will find all features in the first recordset which share all portions of the geometry for features in the second recordset. In this condition, endpoints are allowed to touch. The gmsqContainedBy operator will find all features in the second recordset that share all portions of the geometry for the features in the first recordset. As with gmsqContains, endpoints are allowed to touch.

gmsqContains gmsqContainedBy -- are contained by


2 2 1 line contains point line 1 contains line 2 point c.b. line line 2 c.b. line 1 area contains point point c.b. area area contains line line c.b. area area 1 contains area 2 area 2 c.b. area 1 1

The gmsqEntirelyContains operator is like gmsqContains however, every point is shared. That is, endpoints cannot overlap. The same is true for gmsqEntirelyContainedBy and gmsqContainedBy.

gmsqEntirelyContains gmsqEntirelyContainedBy -- are entirely contained by"


2 2 1 line e.c. point point e.c.b. line line 1 e.c. line 2 line 2 e.c.b. line 1 area e.c. point point e.c.b. area area e.c. line line e.c.b. area area 1 e.c. area 2 area 2 e.c.b. area 1 1

The gmsqSpatiallyEqual operator will find all features in the first

Creating a Custom Application 91 recordset that are identical to features in the second recordset.

gmsqSpatiallyEqual -- are spatially equal

point spatially equals point note that points can only be spatially equal to other points

line spatially equals line note that lines can only be spatially equal to other lines

area spatially equals area note that areas can only be spatially equal to other areas

The gmsqTouches operator will find all features in the first recordset which have at least one point in common with features in the second recordset.

gmsqTouches -- touch
All of the preceding examples will be detected by the touches operator. This is an extremely "catch-all" operator.

Pipe Object Automation


The properties for the pipe are described here.

Property DerivedGeometryFieldName

Description Set this property to include the geometry object resulting from the spatial comparison. This field name must be unique. Applicable only when the SpatialOperator is gmsqWithinDistance. Populated at the completion of the spatial comparison and indicates how many geometry values where skipped during processing. The spatial analysis is completed ignoring these geometries in its output. Specifies the name of the geometry field in the first recordset that will participate

Distance ErrorCount

FirstGeometryFieldName

92 Fundamentals of GeoMedia Development Part I in the spatial analysis. FirstRecordset The set of data representing the left side of the expression. That is, for the expression A overlap B, A is the FirstRecordset. The result of the spatial analysis. If you set the ReferenceFirstRecordset flag to true, the recordset contains the feature instances from the first recordset that satisfy the analysis. If true, indicates that the attributes of the first recordset should be included in the output recordset. If true, indicates that the attributes of the second recordset should be included in the output recordset. Specifies the name of the geometry field in the second recordset that will participate in the spatial analysis. The set of data representing the right side of the expression. That is, for the expression A overlap B, B is the SecondRecordset. A constant that identifies the type of spatial analysis to perform.

OutputRecordset

ReferenceFirstRecordset

ReferenceSecondRecordset

SecondGeometryFieldName

SecondRecordset

SpatialOperator

When using the spatial query pipe, you must follow a certain protocol. Both recordsets must contain geometry in the same coordinate system. If necessary, use the CSSTransformPipe to convert one of the input recordsets to the coordinate system of the other. When using the gmsqWithinDistance operator, the distance value must be in the same unit of measure as the input recordsets. Inverting the comparison will typically not produce the same results. For example, A overlap B will give you the set of features from A that overlap B. However, B overlap A will give you the set of features from B that overlap A. In this lab, you will create a command to allow the user to perform the spatial analysis between two feature classes. If your application manages queries for data subsets, you could also allow the user to choose a query and analyze the data subsets.

Lab 8: Spatial Query


This section of the lab will add the logic to display the list of linear

Creating a Custom Application 93 measurements in the combobox.

Section A: Populating Form


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmSpatialQuery from the Forms list, and select View > Code. 3. Select the Form object, and select the Load procedure. 4. Add logic to retrieve the list of linear measurement types from UnitsOfMeasure object. First create a UnitsOfMeasure object. Store the result in objUOM. Then execute the GetUnitIDs method to retrieve the list of distance unit identifiers and store this in the temporary variable objUnitIDs. Iterate through the collection of unit identifiers and use the GetUnitName method to get the name of each unit from the UnitsOfMeasure object. Finally, put the names in the combobox. 5. Set the default distance/unit to 1 m (one meter). Use the constant igDistanceMeter as an argument to the GetUnitName method on the objUOM variable. 6. Save the project, and compile the executable from File > Make customapp.exe. 7. Test the application. Open a database. Select Window > Activate Map. Select Analyze > Spatial Query. Select the within distance operator to test the display of the list. Cancel the dialog, as the code has not been finished yet to process OK. Summary: In Lab 8, Section A, you retrieved the linear measurement types from the UnitsOfMeasure object and displayed them in the combobox control. You tested the processing of the command to display the special within distance controls when that spatial operator is selected.

This section of the lab will create the input recordsets, set up the pipe, and retrieve the output recordset.

Section B: Processing the Request


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmSpatialQuery from the Forms list, and select View > Code.

94 Fundamentals of GeoMedia Development Part I 3. Select the btnOK object, and select the Click procedure. 4. Add a function to check that a feature has been selected in both treeview controls on the form. Also, if the spatial operator is gmsqWithinDistance, check that a valid distance has been entered. Create a boolean function called ValidSpatialInput that checks both treeview controls and returns a status of True if the user has selected a feature in each. The function also return the names of the two selected features in sFeature1 and sFeature2. If the result is Not true, you will exit the subroutine. 5. Add logic to retrieve the recordsets associated with the two selections. Create an OriginatingPipe recordset using the feature names retrieved in the previous step. Note: In order to get the connection that corresponds to the selected feature each connection node in the treeview control was assigned the correct index in its Tag property. So, get the treeview.SelectedItem.Parent.Tag, convert it to a number and use it as the index into the gobjConnections collection. Populate the Table property on the pipe with the sFeature1 and sFeature2 values and store the results in objRS1 and objRS2 respectively. 6. Add logic to check for matching coordinate systems. If the systems are not the same, perform a transformation of one of the recordsets. Use the GetCSGUID function to retrieve the GUID of each recordset created in the previous step. These are stored in RS1CSGUID and RS2CSGUID. If they are not equal call the function TransformSpatialRS. This function returns transformed recordsets that should be stored in the variables objTransRS1 and objTransRS2. In this routine, a ServerTransService object is created and uses the CreateSimpleTransFromCSMtoServer method to register the recordset GUID as an alternate transformation. Then it creates a CSSTransformPipe and transform the recordset to the map view coordinate system. In the first part of this if statement, assign the transformed recordsets to the FirstRecordset and SecondRecordset properties on the SpatialQueryPipe (objSQPipe). In the second part of the if statement, use the original recordsets (objRS1 and objRS2). 7. If the operator is gmsqWithinDistance, convert the units to the units of the recordsets. Create a UnitsOfMeasure object (objUOM). Get the distance and units from the form. Convert the distance to meters using the ConvertUnitToUnit method. The resulting distance is stored in dblNewDist. 8. Display the results of the spatial query in the map view. Add code identical to that which you did in Lab 4 using the

Creating a Custom Application 95 GetLegendEntry and DisplayTheLegendEntry functions. Only create a legend entry if there are rows in the recordset. This can be determined by testing the EOF and BOF properties. The input to the GetLegendEntry function is objSQRS while the output should be stored in objLE. 9. Save the project, and compile the executable from File > Make customapp.exe. 10. Test the application. Open a database. Select Window > Activate Map. Select Analyze > Spatial Query. Select two features and an operator. Select OK. Processing should complete although you wont see any displayed data. Summary: In Lab 8, Section B, you created the OriginatingPipe recordsets for the selected features. You compared coordinate systems through the CoordSystemGUID values. If they were not the same, you transformed one recordset to the other coordinate system. If the operator was Within Distance, you converted the input value to the units of the data. You reused your existing functions for creating and displaying a legend entry.

96 Fundamentals of GeoMedia Development Part I

Buffer Zone Pipe


This section introduces the BufferzonePipe component. This automation object is used in GeoMedia to create a specialized query that identifies an area around a particular feature commonly known as a buffer zone. This component is typically used to help solve problems involving areas around features. For example, you might want to analyze a specific distance around a road to determine the easement extents and determine which parcels fall in the buffer zone. With the BufferzonePipe component, you are able to create bufferzones around point and linear features. You may also create bufferzones inside or outside of areal features. The resulting buffers may be multiple stacked or multiple ringed. You may opt to display the generated bufferzones as either separate area geometries or merged ones. The BufferzonePipe operates in the same manner as other pipes. You assign the input recordset along with a series of properties that control how the bufferzones will be created. Then, trigger the actual bufferzone operation by requesting the OutputRecordset. In order to view the results from a BufferZonePipe you must save the recordset to a new or existing table. This means that you must have a read/write server connection when using this component (typically an Access database). Once the table is populated with the records in the OutputRecordset, you can create a record legend entry for these results and display them in the map view. Note: The BufferzonePipe does not perform any unit conversions internally. This means that it operates correctly only when the InputDistance is in the same units as the geometry field of the InputRecordset. If these two properties are in different units, then you must convert the InputDistance to be the same units as the geometry field before requesting the OutputRecordset from the BufferzonePipe.

Buffer Zone Automation


The BufferzonePipe contains the following properties. It has no methods. Eight of the properties can be assigned programmatically and two are output properties.

Property BufferType

Description Defines the shape of the bufferzone: gmbtAreaInside, gmbtAreaOutside,

Creating a Custom Application 97 gmbtLinearButtEnd, gmbtLinearRoundEnd, gmbtLinearSquareEnd, gmbtPoint, gmbtPointRinged, gmbtPointStacked. DistanceType ErrorCount Defines whether the distance is constant or varies: gmbdConstant, gmbdVariable. Number of errors encountered in bufferzone operation - typically bad geometry. This is an output value. Distance to buffer around feature if DistanceType is constant. If DistanceType is variable this is name of database field that contains the buffer distance. Name of geometry field in the input recordset. Input recordset. Defines how to merge overlaying buffers: gmbmAll, gmbmNone, gmbmOverlap. Name of geometry field in the output recordset. Result of bufferzone calculation. This is an output. Determines the smoothness of curves and corners. Default value is 0.01.

InputDistance

InputGeometryFieldName InputRecordset Merge OutputGeometryFieldName OutputRecordset Tolerance

Lab 9: Buffer Zone


Section A: Creating a Buffer Zone
In this section of the lab, the custom application will display a buffer zone form upon selecting the Analyze > Buffer Zone map view menu item. You will select the feature to buffer, enter the distance from the feature to measure the buffer zone, and choose the units of measure for that distance. In order to view the buffer zone in the map view, you must also select a database and table to store the results in. The output database must be read/write. The form will automatically default a new output table name (e.g., BufferZone1). You can either accept or modify the name or pick an existing table for the results. Once the OK button is selected, the application will create the BufferzonePipe object, calculate a buffer zone, populate an output table, and display the results in the map view. 1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear.

98 Fundamentals of GeoMedia Development Part I 2. Select frmBuffer.frm from the Forms list, and select View Form. The Buffer Zone form will appear. All of the controls have been placed on the form already. You will add code to the procedure for the OK button to perform the actual bufferzone computation. 3. Double click on the OK button. The code window will appear with the focus set to the btnOK_Click function. 4. Create the BufferzonePipe object. Use the objBufferZoneSrvc variable for this object. 5. Select the SetupBZPipe function. Convert the distance and unit strings from the forms unit selection to meters. You will need to create a UnitsOfMeasure object (objUOM), and pass the distance and unit values from the form to the ConvertUnitToUnit method to get the distance in meters. 6. Calculate the true projected input distance and assign this to the BufferzonePipe. First get the scale factor from the coordinate system with the StorageToProjectionScale method. Use this value (dblGeomFactor) as the denominator and the value in Step 5 (dblNewDist) as the numerator in the calculation the projected distance. Set this property on the BufferzonePipe. 7. Set the BufferType property on the BufferzonePipe. This will vary based on the geometry type of the feature that is to be buffered. Use the Object Browser to find the values for the BufferZoneTypeConstants. 8. Set the geometry field properties for both the input and output tables. The input geometry field name has already been retrieved and stored in strInputGeometryFieldName. 9. Calculate the buffer zone. Return to the btnOK_Click function. Set a recordset variable (objBufferZoneRS) equal to the OutputRecordset property of the BufferzonePipe. 10. Create a new table with the name of the bufferzone feature class. Scroll down to the UpdateOutputTable function. Create a MetadataService object (objMetadataSrvc) and set the connection (objConn) on it. Execute the CreateTableDef method on the associated database within the connection object. 11. Create an originating pipe object to create a recordset for the bufferzone data.

Creating a Custom Application 99 Scroll to the AddLegendEntry function. Create an OriginatingPipe (objOP) recordset (objRS) of the buffer zone feature class. The template already includes the logic to create a coordinate transform for this recordset. 12. Display the buffer zone feature on the map view. Again, in the AddLegendEntry function, add code similar to that which you did in Lab 4 using the GetLegendEntry and DisplayTheLegendEntry functions. The call to GetLegendEntry will have the input objRS and will populate the variable objLE. 13. Save and compile the application. Test the application. Open a map view. Select the Analyze > Buffer Zone command. After pressing the OK button, you should see the mouse pointer change to an hourglass and after a few seconds the bufferzone feature will display in the map view. Summary: In Lab 9, you established the pipe input properties from the users selections. The units specified by the user are converted to meters. The database scale is retrieved and is used in the calculation for the pipes input distance. Meters is the common measurement unit for all internal operations within coordinate systems and measurement. A new database table is created in the warehouse and metadata information added for the table. The table is populated from the output recordset of the pipe. Once the data is stored, you created an originating pipe recordset on the new table. You again reused the GetLegendEntry and DisplayTheLegendEntry functions to complete the command.

100 Fundamentals of GeoMedia Development Part I

Locating Features
In the next lab, we will cover the selection of features in the map view and iteration through the highlighted objects. You will access the recordset corresponding to the selected feature, and finally display the associated database record in a form. The following GeoMedia components are used in this lab: SmartLocateService EventServer and EventControl LocatedObjectsCollection HighlightedObjects

Before beginning the lab, lets review these automated objects.

SmartLocateService Automation
The SmartLocateService is used to locate features adjacent to a point or within a specified region in the map view. It requires a map view dispatch pointer to indicate which map view the point is coming from and a point geometry. This point will start the search for features. You may also use an areal geometry as input to perform a fence locate. Using the Locate method, the SmartLocateService populates a collection object called LocatedObjectsCollection. Here are its properties and method:

Property/Method FenceMode

Description Constant used for fence operations indicating whether to look for features strictly inside the fence or for those intersecting the fence locFenceInside or locFenceOverlap. This only applies if the input geometry is a rectangle. Sets or gets the locate point radius, specified in pixels. Method that takes as input a geometry, a map view pointer, and a LocatedObjectsCollection. The latter argument is populated by the method.

PixelTolerance Locate

Here is an example of how the SmartLocateService is used:

Creating a Custom Application 101 Dim objSmartLocSvrc As New SmartLocateService objSmartLocSvrc.Locate objPointGeometry, ocxMapVw, _ objLocatedObjects The third argument is the LocatedObjectsCollection. You must create this collection prior to calling Locate.

EventControl and EventServer Automation


The input point for SmartLocateService.Locate is typically assigned when the user clicks inside the map view indicating where the locate operation should begin. The EventControl is an OLE control that is used to capture the mouse click event in the map view. This OCX is only used with the map view, and, like the map view control, requires a container typically a VB form. Using the control is easy you simply drop the EventControl on the form at design time and assign it a name (it defaults to EventControl1). Any single container should not have more than one event control associated with it. After starting a command that uses the EventControl to detect mouse and keyboard events, the event control must be told what map view it should listen to. This is done with the AddMapView method. A related object called an EventServer must be instantiated at this point. It acts like a traffic controller for all map view events as the events are fired it directs them to the correct EventControl for proper handling. The EventServer provides the ability to tie more than one map view to a single event control. As such, you can detect mouse clicks in any map view with one EventControl. Here is how you would initiate listening to two map views:
Dim objEvServer As New EventServer ocxEvCtrl.AddMapView ocxMapVw1.Dispatch, objEvServer ocxEvCtrl.AddMapView ocxMapVw2.Dispatch, objEvServer

When working with these two components, it is important to know that once a command is started, you must also terminate it correctly. When using the EventControl to listen to mouse and keyboard events, you must also execute the RemoveMapView method when the command is done. If you fail to do this, GeoMedia (or your custom application) will continue to listen to events causing unexpected results. The EventServer object does not expose any public automation properties or methods.

LocatedObjectsCollection Automation
As noted above, the LocatedObjectsCollection is populated by the SmartLocateService with all features located near the designated point or fence. It is a heterogeneous collection of DisplayedObjects either a

102 Fundamentals of GeoMedia Development Part I RecordsetObject, RecordObject, GeometryObject, or RasterObject. As with any collection, you are able to iterate through it to determine what features are contained within it. Here is an example of retrieving field values associated with a located feature: Set objRS = objLocatedObjects.Item(1).Recordset objRS.Bookmark = objLocatedObjects.Item(1).Bookmark For Each objFld In objRS.GFields strResult = objFld.Name & : & CStr(objFld.Value) Next

HighlightedObjects Automation
When using the SmartLocateService, it is important to note that the map view highlight set and/or select set typically come into play. Once objects are located, they can be added to the map views highlight set or select set. Like the LocatedObjectsCollection, the HighlightedObjects component is also a heterogeneous collection of the same four components associated with a map view (RecordsetObject, RecordObject, GeometryObject or RasterObject). Here is how you would add a feature from the LocatedObjectsCollection to be highlighted in red in the map view:
ocxMapVw.HighlightedObjects.SetDisplayColor RGB(255,0,0) ocxMapVw.HighlightedObjects.Add objLocObjects.Item(1)

Here are the properties and method for the collection:

Property/Method Count SetDisplayColor Add Clear GetRange IsMember Remove

Description Number of highlighted objects in the collection. Set the highlight color. Add an item to the collection. Clear the highlight set. Returns the corner points of the minimum bounding rectangle that holds all highlighted features. Takes as input a pointer to a feature and returns true or false indicating if the object is in the collection. Remove an item from the collection

Creating a Custom Application 103

Lab 10: Locate


This lab selects a feature or features in the map view, and then iterates through the highlighted objects. You will access the recordset corresponding to the selected feature, and finally display the associated database record in a form.

Section A: Locating a Feature


In this section, the custom application will prompt you to select a feature after selecting the Analyze > Attributes item from the map view menu. Before running this command, you must first run the View > Add Feature command so that there are features in the map view to select. The event control will detect when the user has clicked in the map view and then fire a click event. You will add code in the click method of the event control to determine what feature is near the click point using the SmartLocateService. This process will retrieve a recordset and access a particular row. You can then iterate through the recordsets fields and display the results in a textbox on a simple review form. You will review the results, select OK to dismiss the dialog, and then terminate the command. 1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmMap.frm. Delete the existing EventControl control by selecting this control on the form and pressing the delete key. Place an EventControl OCX on the map view. Set the name property on the control to ocxEventControl. 3. Select the Analyze > Attributes menu item. The code window will appear with the focus set to the mnuAnalyzeAttributes_Click function. 4. Set the locate tolerance on the SmartLocateService to five. The service is referenced by the variable, objSmartLocSvrc. 5. Add the map view and EventServer to the EventControl. Use the AddMapView method on the EventControl. The first argument is the ocxMapView.Dispatch pointer. 6. Set the status bar prompt to ask the end user to select a feature. The property on the status bar is SimpleText. 7. Clear the located and highlighted collections. Populate the LocatedObjectsCollection using the SmartLocateService. Scroll down to the ocxEventControl_Click function. First, use the Clear method on objLocatedObjects. Next, use the Clear method on the ocxMapView.HighlightedObjects collection. Now, populate

104 Fundamentals of GeoMedia Development Part I the objPointGeometrys Origin property with the world coordinate values. Then, you will use the Locate method on the SmartLocateService object. Use the Object Browser to check the order of the arguments. 8. Populate the map views HighlightedObjects. Use the Add method. 9. Get the recordset associated with the highlighted feature. Remember to set the bookmark after you have assigned the recordset from the LocatedObjectsCollection. 10. Iterate through the recordsets fields, and display the fields and values in the form. Scroll to the DisplayReviewDialog function. This is listed in the (General) section. Generate a string with the field name and field value for each field in the recordset. Add the string to the listbox on the form. You should always check database values for Null before manipulating them. 11. Add the code to display the form. This action is supported by the Show method. The argument value of one (1) indicates that the dialog is modal. 12. When the user selects the OK button, end the command. Scroll back to the ocxEventControl_Click function. Remember to execute the RemoveMapView method on the EventControl and then clear the two collections. In the Wrapup section of this function release the SmartLocateService, LocatedObjectsCollection, and EventServer objects The variables you will reference are ocxEventControl, ocxMapView, and objLocatedObjects. 13. Save and compile the application. Test the application. Open a map view. Add a feature to the map view. Select the Analyze > Attribute command. Select a feature, and you should see the review form display with a database record that corresponds to the selected feature. Summary: In Lab 10, you placed the event control and established the communication between the view and the control with the event server. The SmartLocateService and the LocatedObjectsCollection are instantiated to perform the Locate operation. The feature that is found first is highlighted and its field names and values are displayed in the dialog.

Creating a Custom Application 105

Creating a Data View


In this section, you will examine the data view control. A data view control displays the nongraphic attributes of a specific feature class or query. That is, the input to the data view control is a recordset. Data views do not display geometry columns, long binary columns, or other columns flagged as not displayable within the feature class metadata. In your application, you will place the control on a form. This is usually referred to as a window of the application. There is no limit on the number of data views you may include in your application. However, there is no inherent relationship between multiple views. You will be responsible for any synchronization of the data display. If your recordsets are based on the OriginatingPipe and you appropriately broadcast changes when you edit a recordset, the other views will reflect the changes since they listen for notification. However, highlighting a row in one view will not highlight the row in the other view unless you programmatically initiate it. The data view supports the following types of manipulation: Show or hide columns Move selected rows to the top of the window Multiple cell selection Multiple column selection Multiple row selection Launching of hypertext attribute values

Hypertext attribute values are determined by the metadata information associated with the field. Hypertext is a special text field that contains the name of a file associated with the record. The data view supports several mechanisms for selecting data, including both mouse and keyboard manipulation. Some of the more common operations are: Mode Cell Key Sequence Left Mouse Click Left Mouse Click Drag Control Left Mouse Click Left / Right Arrow Shift Left / Right Arrow Result Select a cell Select multiple contiguous cells Selects a hypertext cell without activating the value Select the next cell Select a contiguous block of

106 Fundamentals of GeoMedia Development Part I cells Control Left / Right Arrow Up / Down Arrow Shift Up / Down Arrow Control Up / Down Arrow Home Shift Home End Shift End Column Left Mouse Click Shift Left Mouse Click Control Left Mouse Click Left / Right Arrow Shift Left / Right Arrow Select a cell one page left or right Select the next cell Select a contiguous block of cells Select a cell one page up or down Select the first cell Select all cells between the current cell and the first cell Select the last cell Select all cells between the current cell and the last cell Select a single column Unselect all columns and select contiguous columns Select or unselect discontiguous columns Unselect all active columns and select the next column Unselect all active columns and select contiguous columns Adds column selections to the current set of selected columns Single select a row Select contiguous rows Select or unselect discontiguous rows Unselect all active rows and select the next row Unselect all active rows and select contiguous rows Unselect all active rows and select the first row in the next page (rows visible within the data view)

Control Left / Right Arrow

Row

Left Mouse Click Shift Left Mouse Click Control Left Mouse Click Up / Down Arrow Shift Up / Down Arrow Page Up / Down

Creating a Custom Application 107 Shift Page Up / Down Control Page Up / Down Unselect all active rows and select a page of rows Add rows between the current row and one page up or down to the currently selected rows Unselect all active rows and select the top or bottom row Unselect all active rows and select all rows between the current row and the top or bottom Add rows between the current row and the top or bottom to the currently selected rows

Home / End Shift Home / End

Control Home / End

Recall that an event is a message sent from a control to the application. The message indicates some change that has occurred that the program might need to respond to. We have already used the EventControls events to receive mouse and keyboard input through the map view. Unlike the map view, the data view will handle many of the mouse and keyboard inputs and then notify you through an event of what action has occurred. The following events are fired by the data view: Event DeleteRows GotFocus LostFocus NewCell SelectCell Description Not currently fired. The application should include a command to delete a selected row. Standard control behavior. Standard control behavior. Lost focus is usually used to complete any pending action. Not currently fired. Fired when one or more cells is selected by the user. You may control the enabling of menu options when this event is fired. Fired when one or more columns is selected by the user. Also fired when a cell is selected. You may control the enabling of menu options when this event is fired. Fired when one or more rows is selected by the user or when the pointer is set to a particular row. You may control the enabling of menu options when this event is fired.

SelectColumn

SelectRow

108 Fundamentals of GeoMedia Development Part I UpdateCell Fired after the data content of a row is modified. The dataview will update the active row in the database when the focus changes to a different row or view. Multiple cells (fields) within the row may be modified for each UpdateCell event.

Many of the GeoMedia data window commands allow the user to make selections and then perform a command operation. The command will use the methods on the control to find out what cells, columns, or rows are selected. Each selection mode is distinct. That is, you cannot have a combination of items selected - only cells or columns or rows but not cells and columns or columns and rows.

OPTIONAL Lab 11: Data View Construction


This lab covers the basic operation of the data view. You will place the control on your form and allow the user to select a table to display.

Section A: Placing the Control


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmData.frm, and select View Object. The Data Window form will appear. 3. Delete the existing GMDataView control by selecting this control on the form and pressing the delete key. From the toolbox, select the GMDataview control. The cursor will change to cross or plus sign. 4. Create a rectangle by placing the cursor in the upper left corner of the form and dragging to the lower right corner. A white box will appear. The name of the control will default to GMDataview1. 5. Adjust the position of the control to set Top = 0 and Left = 0 in the Properties Window. 6. Select frmData in the Project Window, and select View Code. Select the Form object and the Resize procedure. Add logic to adjust the size of the data view when the form resizes. Use the ScaleHeight and ScaleWidth properties of the form and assign them to the controls properties. 7. Save and compile the application. Test the application. Open a database. Select Window > Activate Data. Select a feature and select OK. The form should appear with the data view as a white square. Test resizing the form and notice the adjustment of the data

Creating a Custom Application 109 view control. Summary: In Lab 11, Section A, you placed the data view control, adjusted its position, and added the logic to automatically resize it.

In this section of the lab, you will display a recordset in the data view.

Section B: Associating the Recordset


1. Return to the Visual Basic project. Select mfrmMain in the Project Window, and select View Code. Select the mnuWindowData object, and select the Click procedure. 2. Add logic to associate the recordset with the data view. Use the SetRecordset method on the control. The inputs to this function are a database pointer, a caption, and, a recordset. The database pointer need not be initialized. Use objDB which is defined in the function. Use the name of the table as the caption. The name of the table can be found by looking at the SourceTable property on the first field of the recordset. Finally, the recordset, objRS is returned from the CreateRecordset function. 3. Save and compile the application. Test the application Open a database. Select Window > Activate Data. Select a feature and select OK. The form should appear displaying the contents of the selected feature. Summary: In Lab 11, Section B, you created a recordset and associated it with the data view.

In this section of the lab, you will change the recordset displayed in the data view.

Section C: Changing the Recordset


1. Return to the Visual Basic project. Select frmData in the Project Window, and select View Code. Select the mnuToolsChange object, and select the Click procedure. 2. Add logic to change the recordset associated with the data view. Again, use the SetRecordset method on the control. The inputs are the same as in the previous section of the exercise. 3. Select frmMap in the Project Window, and select View Code. Select the mnuWindowData object, and select the Click procedure. 4. Add logic to make sure a recordset is active before showing the data window from the active map view.

110 Fundamentals of GeoMedia Development Part I Again, this is the same logic as implemented in step 2. 5. Save and compile the application. Test the application Open a database. Select Window > Activate Data. Select a feature and select OK. The form should appear displaying the contents of the selected feature. Select Tools > Change Contents. Select a feature and select OK. The contents of the view should change to reflect the new feature class. Summary: In Lab 11, Section C, you again used the SetRecordset method to implement the Change Contents command.

OPTIONAL Lab 12: Multiple Key Sort


This lab involves a common operation on tabular data sorting. The GeoMedia product supports a single key sort operation. The SortPipe object is used to perform the sorting. The pipe object actually supports a multiple key sort.

Section A: Setting up the Form


1. Open the project, C:\TGM\Labs\CustomApp\src\customapp.vbp. The project window will appear. 2. Select frmData.frm, and select View Code. Select mnuToolsSort from the object list, and select the Click procedure. The command, Tools > Sort is enabled when the data view is active. The function simply calls SortRecordset. 3. Select modSort.bas from the project window, and select View Code. The file contains the function SortRecordset. The function is fully defined to display the fields associated with the recordset displayed in the data window. 4. Review the code for retrieving the recordset and adding the fields to the form. 5. Test the application. Open a database and display the data window. Select Tools > Sort. Verify that the list of attributes is populated on the left. Summary: In Lab 12, Section A, you reviewed the logic for populating the form with the recordset fields available for sorting.

Creating a Custom Application 111

The remaining section of the lab will create a sort key for each field chosen from the left list and moved to the right list. As fields are dropped from the right, the sort key will be removed. Finally, when the OK button is selected, the data view will be updated with the output of the sort pipe.

Section B: Setting up the Pipe


1. Return to the Visual Basic project. Select frmSort in the Project Window, and select View Code. Select the btnAdd object, and select the Click procedure. 2. Add logic to set the name of the field for one of the sort keys and the ascending flag value. Append the key to the collection on the SortPipe object. The pipe has been created in the Form_Load subroutine. objSortPipe is available globally within the file. You will need to populate the objKey variable, setting the SortFieldName to the currently selected attribute lstAvailable.List(lstAvailable.ListIndex). Use the value of optFlag(0).Value to set the SortAscendingFlag. Finally, append objKey to the SortKeys collection on objSortPipe. 3. Select the btnClear object and the Click procedure. 4. Add logic to remove the fields selected in the right list from the collection of keys. Simply re-create the SortKeys collection on objSortPipe to clear the list of entries. The SortPipe keys collection does not support a remove method. An alternative implementation is to manage your own collection of SortKey objects and delete them from this list. 5. Save the project, compile, and test the application. Open the database, activate the data window, and select Tools > Sort. Test your work by adding several attributes and clearing the sort list. Summary: In Lab 12, Section B, you created a SortKey for each selected field and set the SortAscendingFlag appropriately. You added logic to clear the collection of keys in case the user selected them in the wrong order.

Finally, you will see the sorted recordset. The sort is controlled by the order that the keys are added to the collection. For instance, if you want an alphabetic list of employees by their last name, you would first add the LastName field to the collection. Follow this by FirstName and MiddleInitial to get a list sorted first by last name. Within the same last name, the list is sorted by first names. Finally, when both last and first

112 Fundamentals of GeoMedia Development Part I name are the same, the data is ordered by the middle initial.

Section C: Updating the Data View


1. Return to the Visual Basic project. Select frmSort in the Project Window, and select View Code. Select the btnOK object, and select the Click procedure. 2. Add logic to retrieve the recordset from the data view. Use it as input to objSortPipe. Use the GetRecordset method on the data view control to populate objRS. Assign this to objSortPipe.InputRecordset. Use the temporary variable, objRS, to pass to GetRecordset on the data view control. 3. Retrieve the output recordset from the pipe, and associate it with the data view. Use the SetRecordset method on the data view control. Again, objDB is nothing (no active object assigned to the variable) and the caption can be derived from the SourceTable of one of the recordsets fields. To distinguish the sorted recordset, you should concatenate Sorted to the table name. Use objSortPipe.OutputRecordset as the final argument. 4. Save the project, compile, and test the application. Open the database, activate the data window, and select Tools > Sort. Test your work by adding several attributes and selecting OK. Summary: In Lab 12, Section C, you established the recordset associated with data view as the InputRecordset for the SortPipe. You then retrieved the OutputRecordset from the pipe and assigned it to the data view.

Creating a Custom Application 113

Custom Application Limitations


As presented in our first section, there are three ways to customize GeoMedia: Custom commands Custom application Driving GeoMedia

The third section of the workshop will address custom command development while this section addressed custom application development. We will not pursue the third option in this workshop. To determine how you pursue GeoMedia customization, you need to weigh the advantages and disadvantages of each option. While a custom application allows you better control over the users workflow, it does require more development time than the custom command option. In particular, a custom application must address these items: Persistence of data and settings Document and window management functions Multiple view synchronization Database edit broadcasting On-line help Application delivery

How much extra time is required for development is entirely dependent on the sophistication of the custom application. Lets examine these development areas in more detail.

Persistence
What is persistence? Persistence is the process of saving data and definitions created during an application session. In GeoMedia, the geoworkspace or document is where this information is saved. Of course, your geographic data is saved, but this is written directly to the database and is not included in this discussion. What types of items (objects) are saved or persisted? In GeoMedia, many of the objects that are member objects of the application are persisted. This includes named legends, windows, query folders, and spatial filters. When a window is saved, we also save the position of the window, the associated legend (if its a map window), and subsequently the recordset(s). Naturally, the inverse of persistence is loading the data and definitions.

114 Fundamentals of GeoMedia Development Part I This process restores the application state to the condition the user last viewed. So, do you need persistence? This choice is determined by your application requirements. None of the GeoMedia objects are persistable outside of the geoworkspace. As such, you must maintain all information necessary to recreate the objects. This information must be saved in some file format you determine, and, when your application restarts, you must recreate the GeoMedia objects with the saved information.

Document and Window Management


This area of functionality includes opening and closing of the persistent stores (e.g., the geoworkspace), and the display of map and data windows. Additionally, you may choose to implement common operations like Cascade and Arrange for the window objects. If your application is written in Visual Basic, you will have to implement most of this yourself. In Visual C++, the wizard-generated application usually includes these types of operations. You will simply need to add the appropriate GeoMedia objects.

Multiple View Synchronization


As you work with GeoMedia, you will notice that when an object (a feature instance) is selected in one view, the corresponding object is selected in the other views that contain the object. GeoMedia coordinates this through the documents selected objects collection. When a selection is made, the command (in most cases the Select Tool northwest arrow) adds the item to the collection. The collection then notifies all of the views about the selected items. The views in turn scan their displayed data for a match and select the item if found. This system of notification is unique to GeoMedia and its selected objects collection. If you want to simulate similar behavior in your application, you will need to manage the windows, the selection of data, the broadcast of the selection, and the subsequent data selection in other views. In order to select the correct objects, you will need to understand how to identify each object uniquely. You could simply select the object in all views. However, you usually only want to add a selection when the data is actually displayed. Identification of objects is usually done through key fields in each object. While this is very useful behavior for the application, this task represents a significant development effort.

Database Edit Broadcasting


When you modify values in a recordset, the server will create entries

Creating a Custom Application 115 (rows) in the modification tables. These entries indicate which tables have been modified and the type of modification (add, edit, or delete). If you open the database directly through the GDO interface rather than the connection object, you can turn off this logging. For GeoMedia, the process of logging edits and the broadcast enables the application to reflect the edit in other windows that contain the same features. Broadcast is the process of reading the modification tables, finding all the recordsets affected by the modification, and notifying (sending a message) to all the objects that are referencing this recordset. Lets take an example. In a data window, there is a recordset open on the river table that contains all of the feature instances. One of the attributes is the river depth (RDEPTH). On the legend of a map view is a recordset containing all rivers where RDEPTH < 20. In the data window, the user modifies a row (feature) and changes one value of RDEPTH from 10 to 30. When the broadcast is completed, the map view will display one less river since the modified row no longer meets the criteria of the query. These capabilities synchronized displays and automatic result recalculations are quite powerful. To achieve the same affect in your application, you can use one of two approaches. In the first approach, you simply need to use the connection object for database access and create all recordsets through the originating pipe object. Then when your commands edit data, you must call Connection.BroadcastDatabaseChanges. The other alternative involves using GDO directly for the database open and recordset creation. It then becomes the applications responsibility to process the modification tables, find the recordsets, and recreate the recordset to reflect the changes. The GDO interface does not support a refresh or requery method so you will need to retrieve the data again. If your application does not allow data edits, then you need not worry about this. Alternatively, you may deem it acceptable to allow the views to lose synchronization. The first alternative to achieving this is quite simple if considered from the outset of your development.

On-Line Help
GeoMedia includes extensive documentation about the products function and command processing. While you might still reference this material, it is highly likely that you would write your own help to accompany the application.

Application Delivery
Whether you add one command or build a complete application, you need to consider how you will move your software to each users machine. If GeoMedia is a prerequisite (as is most often the case), and you are adding commands, you can create a compressed file, and create a series of command files to automate registration of the commands. One

116 Fundamentals of GeoMedia Development Part I command will be the setup command that automates the configuration of the GeoMedia menus. You will need to run GeoMedia and your setup command on each machine. An alternative to the compressed and command files is a setup application. Even with this alternative, you will need to create and run the setup command. You can take a similar approach to the installation of a custom application. In this scenario, you wont need the setup command. If you have established the legal OEM agreement with Intergraph to redistribute the GeoMedia object DLLs, you will be responsible for the delivery and registration of all the necessary files. This includes object DLLs, type libraries, and OCXs as well as supporting DLLs that GeoMedia uses. You will need to update the registry with the path to the DLLs or put your executable in the same directory as the supporting object DLLs. Application delivery is a necessary component in your development process. It is highly advisable that you begin this process early - as soon as you have a working subset of your application. It is imperative that you test the installation on a non-development machine. Also, you need to include an uninstall mechanism to remove the software components from the users machine.

Summary
The choice of customization technique is yours to make. Only developers and companies who have entered into legal OEM agreements with Intergraph can redistribute GeoMedia DLLs. So, in most cases, you must install GeoMedia whether you use the product or just the objects. Although at the outset, a custom application may appear to be the simplest approach, be sure to consider the long term project requirements. You may find that you quickly end up recreating GeoMedia.

Creating a Custom Application 117

Summary
The overall objective of this section was to familiarize you with the creation of an independent custom application that uses GeoMedia objects. To this end, you learned how to do the following operations in a Visual Basic application. Make a connection to a warehouse through a GDO server Create and manipulate recordsets Use a MapView control and display data in it Customize the display characteristics of your data with styles Perform spatial analysis with spatial queries and buffer zones Locate your data Display the attributes of your data in a data view and sort it

In doing so, you have utilized the following objects: Connections, Connection GDatabase GRecordset, OriginatingPipe GFields, GField GMMapView Legend LegendEntries RecordLegendEntry Styles GMNorthArrow GMScaleBar MetadataService SpatialQueryPipe BufferZonePipe SmartLocateService EventServer and EventControl LocatedObjectsCollection HighlightedObjects

118 Fundamentals of GeoMedia Development Part I

GMDataView SortPipe

Can You Answer These Questions?


1. What is notification? What is its significance? 2. What is the component hierarchy of the GDO components? 3. What can you use instead of GDatabase.OpenRecordset? Why? 4. What is persistence? 5. What is the significance of GDO over DAO? 6. What is a ProgID? When is it used? Where is it stored? 7. How do you find the PrimaryGeometryFieldName of a table? Of a recordset? 8. Complete these descriptions in the context of GeoMedia programming. A table is a ???. A column is a ???. A row is a ???.

Adding Commands to GeoMedia 119

Adding Commands to GeoMedia


Introduction
The simplest approach to GeoMedia customization involves the addition of commands. By adding commands, you can expand the capabilities of GeoMedia while focusing solely on the value added code. That is, you need not implement the mechanics of an application since this framework is inherent in GeoMedia. This section of the workshop will present the types of commands, how to create a command, debugging commands, and the creation of modal and modeless commands.

Topics
1. GeoMedias Command Wizard 2. Command Types 3. Creating the Command Skeleton 4. Modal Commands 5. Modeless Commands

Objectives
At the end of this section, you will be able to: 1. Describe the operation of the Command Wizard 2. Describe the types of GeoMedia commands that may be created 3. Describe command stacking and priorities 4. Implement a modal command 5. Implement a modeless command 6. Use the following objects: EventControl MapView PointGeometry Query EventServer Legend LinearStyle QueryFolder RectangleGeometry RecordLegendEntry GeometryEditService OriginatingPipe

120 Fundamentals of GeoMedia Development Part I

ExtendedPropertySe t CSSTransformPipe

MetadataService

Connection

GeometryStorageService ServerTransService

Labs
13. Hello GeoMedia! 14. Custom Reports 15. Magnify View

Adding Commands to GeoMedia 121

GeoMedias Command Wizard


GeoMedias Command Wizard is a Visual Basic add-in. An add-in automates common tasks. In this case, the task is the creation of a GeoMedia command. The add-in becomes accessible from the Visual Basic development environment. The term wizard is used to describe a part of a program that guides you through a series of steps to accomplish a task. Note: If Visual Basic is not installed when you install GeoMedia, you will need to manually add the wizard to make it accessible from Visual Basic. Run the regwiz.exe from the c:\program files\GeoMedia\wizard directory. In Visual Basic, select Add-Ins > Add-In Manager, and check the GeoMedia Command Wizard entry. Select OK. The Command Wizard creates a Visual Basic project that functions as a command for GeoMedia and edits or deletes command set information. Commands are separated from the GeoMedia framework through an interface. This means that each command is an automated object. Through automation, the application and the command components work together. The GeoMedia framework and the individual commands are automation servers. The framework exposes the application objects to support application programmability and customization. The framework expects individual commands to expose an automation interface which supports the commands side of communication with the framework. The Command Wizard supplies the automation interface for you. The interface includes the following methods. These will be reviewed as we discuss the types of commands. Note: While each command is an automated object, you cannot call one command from another. Additionally, you cannot call GeoMedia commands from an independent application. The PageSetup and Print commands are exceptions to this rule.

Property/Method IsDone

Description Indicates whether or not the modeless command has completed processing. This property should be set to True if the command has completed processing and requests termination.

122 Fundamentals of GeoMedia Development Part I

Initialize

Called when a command server is created. Currently, the server is created only once within a GeoMedia session. Called to start the command. A modal command should show its main form. Modeless commands should set their IsDone property to False and connect to their views if they are also view listeners. This method is called multiple times during the command server objects lifetime. Called by command manager to determine if the command can be deactivated. This method allows the command to perform any user interaction necessary to complete any pending actions. Called by the framework when custom enabling has been specified. The command logic must determine if conditions are appropriate for the command to execute. Called by the framework when custom activation has been specified. Not currently supported? Called to make the command become inactive. Called when a new map view is opened. Called when a map view is closed. Called when your command is suspended. Called when your command is reactivated. Called when your command server is about to be destroyed. This currently occurs when GeoMedia is exiting. Since this occurs after the workspace is closed, you must release global variables associated with the workspace prior to this method.

Activate

CanDeactivate

CanEnable

CanActivate Deactivate AddView RemoveView IgnoreEvents RestoreEvents Terminate

The wizard begins by asking for the type of operation: add, edit, or delete command. A command edit allows you to change the status message, tool tip, and enabling conditions for a command. A delete request removes the command from the command set. An addition creates a new command project. The second step of the wizard, Choose Project Location, prompts you to choose a directory for the command - optionally creating a new directory. Its a good idea to have a central location for all of your command

Adding Commands to GeoMedia 123

directories, although this is not required. The third step of the wizard, Choose Command Name, gathers information about the command, including the name, the status message, and the tooltip. A status message appears in the applications main window as you drag your cursor over the menu item. The tooltip appears as you hold your cursor over a toolbar button. It is also used as the name of the command in the Tools > Customize command list. The command name in combination with the Project Name from the previous step comprises the ProgID for the command. GeoMedia uses this to create an instance of your command class. The fourth step of the wizard, Command Classification, indicates the nature of the command processing. Modal commands generally display a dialog that prohibits selection of any item (vector data, menu items) until the dialog has been dismissed. Essentially, a modal command has complete focus of the application, and nothing else can occur until the command completes. Modeless commands may display modeless forms and allow other parts of the application to process while they are active. Note: Due to limitations in Visual Basics OLE Server implementation, you cannot display a modeless dialog in an OLE DLL. Modeless dialogs must be created in VC++. Alternatively, you can use the DockableControl object in the GeoMedia framework to host an ActiveX control. Visual Basic 5.0 supports the creation of these controls and they can be used like modeless dialogs. Refer to the article, mk:@ivt:kb/source/vbwin/q171978.htm, on Microsofts Developer Network. Note that Visual Basic 4.0 did not support any modeless dialogs in OLE DLLs. In Visual Basic 5.0, if the application (EXE) is built with Visual Basic 5.0, modeless dialogs can be created in an OLE DLL. GeoMedia is built with Visual C++ and does not provide the interface required for the communication with the application message loop required to support modeless VB dialogs. The fifth step of the wizard, Choose Form Name, requests the name of the form and an indication of desired position. The wizard generates the necessary code to position the form.

124 Fundamentals of GeoMedia Development Part I

If you specified that the command is modeless, the View Listener step asks if you will listen to events exposed through the map view -- like mouse clicks and keyboard input. The View Listener Requirements step asks for information about the type of views you will listen to. Finally, the View Listener Command Type step determines the classification or priority your command will take. Refer to Command Types for information on these selections. The sixth step of the wizard, Command Enabling Conditions, allows you to control when the command is enabled on the menubars. Specification of the appropriate set of enabling conditions can simplify your commands error handling. The wizard provides an extensive list of conditions that can be checked for. You may select as many conditions as necessary. Some conditions preclude others. For example, if your command requires that an element must be in the select set, you need not specify that a geoworkspace must be open since you cannot select an item without an open workspace. The set of enabling conditions cover aspects of dataview, queries, connection, windows, and the select set. Additionally, you can specify your own enabling conditions. If you specify custom conditions, you must implement the CanEnable method on the command manager interface. The final step, Complete, simply summarizes the activities and indicates the files that will be generated. The files are divided into two subdirectories within your project. When you select Finish, the wizard will generate the following set of files.

File src\GeoMediaCommand.vbp src\MyCommand.cls src\modMyCommand.bas src\frmMyCommand.frm src\MyCommand.txt bin\MyCommand.ini

Purpose / Content Visual Basic project OLE class definition and command interface functions Form centering logic and globals Default form Text file which recaps the command specification information Specification of command set information used when the command is registered for access by GeoMedia

Once you compile your command, it can be positioned on a GeoMedia menubar and executed. If you need to move the command to another

Adding Commands to GeoMedia 125

machine, you need only take bin\MyCommand.dll and bin\MyCommand.ini. You will need to install the command on the other machine using the installation program: c:\Program Files\GeoMedia\Program\Installusrcmd.exe MyCommand.dll MyCommand.ini This program registers the command and updates the command set on the other machine. Because commands are written as OLE servers, they can be easily reused in other projects. Of course, the ease of reuse is tied to how well you have generalized your processing and eliminated any dataset-specific dependencies.

126 Fundamentals of GeoMedia Development Part I

This page is intentionally blank.

Adding Commands to GeoMedia 127

Command Types
GeoMedia supports two fundamental classifications of commands: modal and modeless. Modal commands take control of the entire application until the commands complete their functions. This group includes all of the commands that display dialog boxes to collect user input before performing a task (File Open, File Send Mail), all object-action commands which are enabled when the required type of object is selected (user interaction occurs before the command is started), and all commands which require no further user interaction after the command is started. These command manager interface methods are applicable to modal commands: Initialize CanEnable (if custom enabling specified) Activate Terminate

Modeless commands briefly take control of the application to create or connect to windows. These commands consist of two phases: setup (modal) phase and the listening phase. During the setup phase, these commands may create new modeless windows or start listening to events at existing windows. Modeless commands then return control to the application. After the overall application is released to respond to events, these commands are still active. Modeless commands listen for events at the windows they create or to which they attach. Modeless commands remain active until they receive an event instructing them to deactivate. Some modeless commands require the user to interact with GeoMedia while the form is displayed. Such a form is referred to as modeless. If you need to have the form displayed while you are moving the mouse over the application window, the form must be modeless. Commands that require modeless forms must be written in Visual C++. A modeless command has two phases: setup, which is typically modal in nature, and listening, during which the command responds to events. In addition to the methods that modal commands implement in the command manager interface, all modeless commands also implement: Deactivate

If you specify a command as modeless, a further classification process occurs. If you want your modeless command to receive mouse and keyboard events, it is a map view listener command. When writing a command that acts as a map view listener, it is very important that you

128 Fundamentals of GeoMedia Development Part I

understand the calling sequence of the command manager interface methods in your command class. Modeless commands that are view listeners will implement the remaining command manager interface methods: AddView CanActivate (if custom listening specified) CanDeactivate RemoveView IgnoreEvents RestoreEvents

So that GeoMedia can control the simultaneous processing of modeless commands, modeless commands are classified. Through this classification, we establish a command stacking priority. There are four classifications of map view listeners: 1. Selection 2. Placement / Editing 3. View Change 4. Tracker A Selection commands primary purpose is the selection of data elements. In GeoMedia, this is the Select Tool or Northwest Arrow. Only one command from this group can be listening to a single map view at a time. It is possible to have different selection commands active if you have multiple views active and they are listening to only one view. A Placement / Editing commands primary purpose is the creation or modification of data. Only one command from this group may be active. In GeoMedia, Insert Feature and Modify Feature Geometry are examples of this type. A View Change / Define Subview commands purpose is to modify the extents of the view or extract information about the view. In GeoMedia, Print and Snapshot are examples of this type. For each of the command group types above, the initiation of a new command in the same group terminates another command of the same type, and it will terminate any other type of higher priority if the other command allows the termination request. A new command from a higherpriority classification temporarily steals events from the active selection command. The final group, Tracker, does not participate in the command-stacking

Adding Commands to GeoMedia 129

process. Any number of tracker commands may be active at the same time. In GeoMedia, the Coordinate Readout and ScaleBar are examples of tracker commands. The commands exhibit the following priorities:

Priority Highest Intermediate Lowest

Command Type View Change Placement / Editing Selection

Command priority provides the capability to stack commands. For example, if you initiate the selection tool (Northwest Arrow in GeoMedia) and then select a placement command, you have suspended the selection tool command. When you complete the placement command, the selection tool command will resume. In a similar fashion, if you select zoom in while the placement command is active, the placement operation is temporarily suspended. When you complete the zoom operation, the placement command will resume. The tracker commands operate independently of all other command types. That is, they have no effect on and are not affected by the activation of other commands. For any single view, GeoMedia can have three commands stacked and any number of tracker commands processing. Initiation of commands defined as modal do not explicitly affect any stacked commands in the modeless groups.

View Listener Hints and Tips


All of the view listener types of commands exhibit the following behavior: 1. When the command class is first created, the Initialize method is called. Each time the command is selected, the Activate method is called. 2. Since your command can be selected even though it might already be running, you must handle the reactivation. For example, dont reattach to views that youre already listening to. 3. You will normally attach to the map view during the Activate method by calling the Add method on the view listener object. 4. Deactivate is only called during application shut down if your command is currently active.

130 Fundamentals of GeoMedia Development Part I

5. If you support a self termination (i.e., honor the ESC key), then you will typically call your own Deactivate method. Do not rely on GeoMedia to do this. 6. If another command of lesser or equal priority is selected while your command is active, your CanDeactivate method will be called for each map view that is in conflict. If your command returns True for all the CanDeactivate calls, then your RemoveView method will be called for each conflicting view. When the last map view is taken away from your command, then your command should set IsDone to True and reset to its inactive state. Essentially, selecting another command of equal or lesser priority will cause your command to terminate. 7. If another command of greater priority collides with your command at a map view, then your IgnoreEvents method will be called for each view in conflict. This essentially suspends your command. When the other command completes, your RestoreEvents method will be called for each view in conflict. 8. If your command has requested notification of new views, your AddView method will be called either if the command is active or if it is ignoring events. 9. When a map view window is closed, the CanDeactivate method will be called for all commands that are active or ignoring events for the window. If any CanDeactivate method returns False, the window will not be closed and the commands continue processing. If all CanDeactivate calls return True, then RemoveView is called on all the commands referencing the view. 10. When GeoMedia exits, all map view windows are closed. This will in turn cause all view listener commands to self terminate when their last view is removed. All remaining commands will have their Deactivate method called. Finally, the Terminate method for all loaded commands will be called. 11. If you have not specified custom enabling or activation rules, then return True for CanEnable and CanActivate. If you have custom rules, you will need to examine the condition of the application and return True if you can enable or activate. Return False if the conditions are not correct for your command to run successfully. 12. The IsDone property should be set to True when your command is inactive. You are inactive if all operations have been completed and you are waiting for the next Activate request. Otherwise, return False.

Adding Commands to GeoMedia 131

Creating the Command Skeleton


This section provides you with hands-on experience with the command wizard and accessing your command in GeoMedia. Each step of the wizard is accumulating information about your command for GeoMedias command set. Once you have completed all of the steps, your command will be available for use within GeoMedia.

Object Browser
Since you will be creating commands that utilize GeoMedias objects, you need to be familiar with the object browser in Visual Basic. This tool displays the objects and their properties, constants, and methods that are available in object (type) libraries. You can also examine your own project modules and procedures. The object libraries that are visible in the browser are controlled by the references you have established in the project. By default, the GeoMedia Command Wizard includes most of the components type libraries associated with GeoMedia, as well as the MapView, DataView, and EventControl custom controls. Type Library Description Intergraph GeoMedia Event Control 2.0 Intergraph GeoMedia Map View Control 2.0 Intergraph GeoMedia Framework 2.0 Intergraph GDO 2.0 Object Library Intergraph GeoMedia ExtendedPropertySet 2.0 Intergraph GeoMedia Basic Utilities 2.0 Intergraph GeoMedia Client Support 2.0 Intergraph GeoMedia Coordinate Systems 2.0 Intergraph GeoMedia Map Viewing 2.0 Object Types Custom control for receiving mapview events Custom control for displaying geographic data GeoMedia application and workspace objects GDatabase objects Support for extension objects Geometry definitions Connections and services Coordinate system objects Legend and style definitions

132 Fundamentals of GeoMedia Development Part I

Intergraph GeoMedia Services 2.0 Intergraph GeoMedia Services 2.0 Intergraph GeoMedia Database Pipes 2.0 Intergraph GeoMedia Geometry Pipes 2.0 Intergraph GeoMedia GeoMath 2.0 Intergraph GeoMedia Thematic Display 2.0 Intergraph GeoMedia Raster 2.0

Metadata constants Metadata and preference set objects Attribute-based pipe objects Geometry-based pipe objects Math function definitions Thematic legend entries Raster manipulation objects

You may need to add these references: Intergraph GeoMedia CAD Server 2.0 Intergraph GeoMedia Feature Controls 2.0 Intergraph FRAMME GDO Extension 1.0 Object Library Intergraph GeoMedia North Arrow Control 2.0 Intergraph GeoMedia Scale Bar Control 2.0 Intergraph GeoMedia Coordinate System Dialog Control 2.0 Intergraph GeoMedia Data View Control 2.0 Intergraph GeoMedia Controls 2.0

GeoMedia includes additional DLLs that appear in the browser. However, they contain commands and are not developed for reuse by other software. To add an additional type library, select Tools > References... and then search through the list by selecting I to find the Intergraph libraries. The browser does not alphabetize the list. Check the appropriate library and select OK. To add an additional control, select Tools > Custom Controls.... You may get a series of warning messages indicating Object server not correctly registered. Simply dismiss these dialogs. Check the appropriate control and select OK. Within the browser, you first select the library of interest. The available classes will appear for the library. By selecting a class, you will see the associated properties and methods. Selection of a method will expose the methods signature (call sequence). Within an active method or property, you can select Paste to copy the information to the cursor location within

Adding Commands to GeoMedia 133

your code. If you pasted a method, the resulting code will use named arguments. Through this technique, you can specify the arguments to the method in any order. If you do not use named arguments, then the arguments must be in the same order as in the method definition. You may also select the help button to activate the automation help file. This provides you with specific information about the selected object, method, or property.

GeoMedias Menus and Toolbars


After you compile your commands DLL, you will associate your command with a menu item within GeoMedia. There are three menus in GeoMedia. The menu that appears depends on the active window. When no window is open (i.e., no workspace is open), the window type is none. When a map window is active, the window type is Map. Finally, when a data window is active, the window type is Data. If your command is applicable to all types of windows, you will need to add it to each menu. To associate a command to a menu, you will use the Tools > Customize... command. This command allows you to add or remove commands. You may also add a new section on the menubar. You may also customize the GeoMedia toolbars. The Tools > Customize... command is also used for this operation.

Lab 13a: Hello GeoMedia!


This lab will create a very simple modal command, attach it to the GeoMedia menus, and run the command. Since the standard programming exercise is always Hello world for any new language, we will oblige with Hello GeoMedia!.

Section A: Using the Wizard


1. Initiate Visual Basic by selecting the desktop icon or from the Start menu. A dialog New Project will appear; select OK 2. Select Add-Ins > GeoMedia Command Wizard... If this menu item does not exist, select Add-Ins > Add-In Manager... and select GeoMedia Command Wizard. Then reattempt step 2. The Introduction dialog will appear. 3. Select Create a new project for a command., and select Next >. The Choose Project Location dialog will appear. 4. Under Project Location:, select c:\TGM\Labs.

134 Fundamentals of GeoMedia Development Part I

5. Under New Subdirectory Name:, enter Lab13. Select Next>. The Choose Command Name dialog will appear. 6. In Command Name:, specify Hello. 7. In Command Description:, specify Welcome to GeoMedia. 8. In Command Tool Tip:, specify Hello GeoMedia. Select Next >. The Command Classification dialog will appear. 9. Select Command is Modal. Select Next >. The Choose Form Name dialog will appear. 10. Select Form is centered in the Intergraph application window. Select Next >. The Commands Enabling Conditions dialog will appear. 11. Select GeoWorkSpace is open. Select Next >. The Complete dialog will appear. 12. Select Finish. You will be prompted to open the new project. Select Yes. You may also be prompted to save the initial project. In this case, you may select No. In your normal development activities, you may need to specify Yes. 13. Save your project with File > Save Project. 14. Create the server DLL by selecting File > Make Hello.dll... A dialog will appear asking for the output location. 15. Select C:\TGM\Labs\Lab13\bin. Select OK. 16. Collapse or exit Visual Basic. Summary: In Section A, you successfully used the command wizard to create your Visual Basic command project.

Section B: Adding the Command to GeoMedia


1. Start GeoMedia. Create a new geoworkspace (File > New GeoWorkspace...). Use the default template. 2. Connect to the sample warehouse. Select Warehouse > New Connection... and select Access and the Us Sample Data.mdb in the c:\warehouses directory. All of the default options on the wizard are

Adding Commands to GeoMedia 135

acceptable. 3. Save your new workspace so that you may use it in the other lab exercises. Select File > Save GeoWorkspace..., and specify any name you choose. Store it in the c:\geoworkspaces directory. 4. Select Tools > Customize... The Customize dialog will appear. 5. Select the Custom category from the Categories: list. The Commands: list will update to reflect all user defined commands. 6. Select the Hello GeoMedia command. 7. Select Help from the Change what menu: list. 8. Select Add, and select Close. Your command is now associated with the Map window type menu. If you want the command available for all of the windows, repeat the process for each of the Window Type: entries. 9. Select Help > Hello GeoMedia. The default dialog should appear. 10. Select OK, and select File > Exit to terminate the session. Summary: In Section B, you successfully added your command to the GeoMedia menus. You are able to run your command. It will display the default dialog created by the Command Wizard. You can also create a command that will configure the GeoMedia menus.

Section C: Updating Code


1. Return to the Visual Basic project for your command. 2. If the Project Explorer window is not already displayed, select View > Project Explorer. Under the folder GeoMediaCommand (GeoMediaCommand.vbp) and under the subfolder Forms, there is the form frmHello (frmHello.frm); double-click on it. The default form will appear. 3. Delete all of the controls ( two label controls and one button control ). Simply select the controls with the mouse, and press the delete key. 4. Display the Properties Window (View > Properties Window). Select the Font property, and select the ... button.

136 Fundamentals of GeoMedia Development Part I

The Font dialog will appear. 5. Change the Size: property to 8. Select OK. By setting the font on the form, all controls placed on the form will inherit their size and style from the form. In most cases, you will use the same size font on all controls. 6. Display the Toolbox (View > Toolbox ). Select the label control button. The cursor will change to a small cross hair (+). 7. Click and drag to create a rectangular area to hold the text string. In the Properties window, select Caption. Key in Hello GeoMedia! 8. Select Font, and select the ... button. The Font dialog will appear. 9. Change the Size: property to 24. Select OK. This label will be larger for added emphasis. 10. Select the button control button in the toolbox. The cursor will change to a small cross hair (+). 11. Click and drag to create a rectangular area for a Close button. In the Properties window, select Caption. Key in Close. 12. In the Properties window, select (Name), which is located at the top of the property list. Key in btnClose. 13. In the Properties window, select Cancel. Select True. This property controls the dismissal of the form when the ESC key is selected. 14. You may wish to set standards for you control sizes. Most GeoMedia buttons are 350 twips by 1125 twips; if you choose these dimensions, select Height and key in 350, then select Width and key in 1125. A twip is a screen-independent unit used to ensure that the placement and proportion of screen elements in your screen application are the same on all display systems. A twip is a unit of screen measurement equal to 1/20 of a printers point. There are approximately 1440 twips to a logical inch or 567 twips to a logical centimeter (the length of a screen item measuring one inch or one centimeter when printed). 15. Double click on the button control. The code for frmHello will appear.

Adding Commands to GeoMedia 137

16. Delete the definition for Command1_Click (located under the (General) object), since this was the logic for the default button that we deleted. 17. Add the code to btnClose_Click to Hide the form. Notice the declaration Option Explicit at the top of the file, under the object (General) and the method (Declarations). Be sure to include this in EVERY code file (.cls, .bas, .frm). This declaration forces a compile time check for declaration of all variables. You can choose Tools > Options (under the Editor tab) and check Require Variable Declaration to have it automatically included in all the projects code files. 18. Save your project with File > Save Project. Select File > Make Hello.dll... Save the DLL on top of the one created in Section A; reply Yes to the dialog box asking you if you want to replace the old DLL. 19. Collapse or exit Visual Basic; save the changes to GeoMediaCommand.vbp and frmHello.frm. 20. Start GeoMedia, and open the workspace you created in Section A. 21. Select Help > Hello GeoMedia. Your commands dialog should appear. 22. Select Close and select File > Exit to terminate the session. Summary: In Section C, you made some basic modifications to the Visual Basic project to display your own message. You included the code to end your command and tested it within the GeoMedia environment.

Debugging GeoMedia Commands


Debugging within the Visual Basic environment is quite powerful and productive. In most cases, you will be able to debug your GeoMedia commands. However, there are situations in which you will not be able to successfully debug. The problems are related to the discussion of inprocess versus out-of-process manipulation of objects. When a command runs normally in GeoMedia, it is in-process. However, when it is run from Visual Basic, it is out-of-process as the Visual Basic executable is also running and controlling the command server. There are certain operations on GeoMedia objects that do not function correctly when executed out-of-process. The feature selection control does not function correctly out-of-process. Additionally, modeless commands are very

138 Fundamentals of GeoMedia Development Part I

difficult to interactively step through since the debugger interaction changes the normal interaction with the command. Certain general rules should be applied in the development of your commands for successful development and debugging. For any functions or procedures that manipulate objects in some way such that they might encounter errors, you should always include an error handling clause. Refer to the Err Object documentation in VB help for more information on this construct. Additionally, you should always include Option Explicit in every file in your project. This forces method and property names as well as argument sequences to be checked during compilation. Finally, use strong typing wherever possible rather than Object declarations. For commands that will support interactive debugging, create your command, compile it, and integrate it into the framework menus. Now, open your Visual Basic command project. Set any breakpoints needed in the source code. Select the Run > Start (or the Start button). Now start GeoMedia. When your command is selected, you will break at the locations you set. All normal Visual Basic debugging capabilities are available to you. Always continue (with the Start command) at the end of your functions and subroutines. NOTE: You will have to exit GeoMedia to exit your debugging session. When you have made code corrections, select Run > Start again and repeat the process. You do not need to rerun installusrcmd.exe, nor do you need to reconfigure your menus. If you do not exit GeoMedia, you will get an error when you attempt to recompile your command DLL. This is because GeoMedia is still holding a reference to the command DLL in memory. To avoid causing a GeoMedia crash on exit from the application, be sure and release all variables when the command is completed. Do NOT wait for the Terminate function to be called. This function is only called on exit of the application. Releasing document and recordset variables at this point will result in application crashes. If your command is not suitable for interactive debugging, you will need to use status prompt messages and/or MsgBox calls to diagnose the cause of your errors. You can use the application status bar to display information messages about your command progress. This call is: gobjGeoApp.SetStatusBar Step 1 preparation, 1 This technique is less intrusive than a message box. If you opt for message box displays, you should consider writing a DebugMsgBox function. For example:

Adding Commands to GeoMedia 139

Global Const iCurrentSeverity = 5 Public Function DebugMsgBox( iSeverity As Integer, _ strPrompt As String ) As Long If iSeverity >= iCurrentSeverity Then DebugMsgBox = MsgBox strPrompt, _ vbOKOnly + vbExclamation, _ My Command Title Error Else DebugMsgBox = vbOK End If End Function With this type of function, you can retain your diagnostic information without continual editing of your code while controlling the extent of the debug information displayed. To turn off diagnostics completely, you can exit the function immediately.

Lab 13b: Debugging Commands


1. Start Visual Basic. 2. Open the project for the Hello GeoMedia! lab. This file is c:\TGM\Labs\Lab13\GeoMediaCommand.vbp. 3. In the Project Window, under the GeoMediaCommand (GeoMediaCommand.vbp) folder and Class Modules subfolder, select Hello (Hello.cls) from the Project Window and select View > Code (or double-click on Hello (Hello.cls)). 4. Select the Initialize method, and set a breakpoint on the line initializing the commands application object by depressing the function key F9 or through Debug > Toggle Breakpoint. 5. Select the Activate method, and set a breakpoint on the line which calls the CenterForm subroutine. 6. Start your command by selecting the Start button Start command. The debug window -- Immediate -- will appear. 7. Start GeoMedia, open the stored workspace, and select your command. or the Run >

140 Fundamentals of GeoMedia Development Part I

8. Step over the initialization statements, either by depressing the function key F8 or through Debug > Step Into, and select Start before you reach the end of the Initialize method. 9. Step into the CenterForm subroutine. 10. Step over the statements (using SHIFT+F8 or Debug > Step Over) until you are positioned at the assignment statement for iMidY. 11. In the Debug Window, key in: print iMidX. The debugger will display the current value of iMidX. 12. Select Start to continue execution of the command. 13. Dismiss your command by depressing the Close button, exit GeoMedia, and then exit Visual Basic. Summary: This section showed you how to establish the debug environment for commands and some of the basic operations available for debugging.

Adding Commands to GeoMedia 141

Command Writing Guidelines


While each organization will implement its own development standards, there are a few recommendations that are emphasized here. Use Option Explicit within EVERY source code file. This forces you to declare all variables and allows the compiler to perform type checking for you. Ensure there is a Release of each object variable corresponding to every Set. Release of an object is achieved by setting the variable to Nothing. Without releasing objects, you degrade memory management within the application. Use meaningful variable names. Some naming conventions are suggested in the appendices. Include liberal comments in your source code. Minimize the use of global variables. Include an error handler in every function and subroutine that might fail under some circumstance.

142 Fundamentals of GeoMedia Development Part I

Modal Commands
Modal commands typically display a dialog to the user. They are most often used to gather information from the user prior to processing. Although a modal command can affect other views in GeoMedia, it does not receive input from the user outside of the dialog. Modal commands are much simpler to write than modeless commands. Since modal commands are not considered in the command stacking and priority, you do not need to program for interrupts or conflicts. For any modal command, you must implement the following methods on the command manager interface for the command class.

Method Initialize Activate Terminate

Description Stores the application pointer and performs any one-time set up operations for the command. Performs the processing of a single command initiation. Performs any command clean up, such as releasing the application pointer.

The wizard-generated code provides the correct defaults for the remaining methods.

Lab 14: Custom Reports


In this example, the code you write will allow the end-user to create a custom QueryFolder for storing user-defined reports (queries). A rudimentary interface will be defined to create new queries. The command will also allow the end-user to run the query to add it to the active window. Finally, the command allows the end-user to delete the query. The recordset creation will be written to include a spatial filter. GeoMedia maintains three sets of queries. Each set (QueryFolder) contains Query objects that are associated with GRecordset objects. Because these sets are centrally available, GeoMedia will reuse a recordset rather than creating another one when the criteria for the recordset are the same. This reuse eliminates duplicate queries issued to the servers, duplicate retrieval of data from the servers, and additional overhead for the GRecordset and dependent objects.

Adding Commands to GeoMedia 143

Lets look at the object hierarchy for the QueryFolders presented in this diagram.

While there is a single, unnamed QueryFolder associated with the document, there are three subfolders used by GeoMedia. These are: Features - contains query objects for recordsets created on full or spatially filtered feature tables Images - contains query objects for recordsets created on image tables Queries - contains query objects for user defined queries

Now lets take an alternate approach to viewing these objects.

In this lab, you will create a command that supports the addition of new QueryFolder objects in the collection associated with the documents base QueryFolder. The object reference is: gobjGeoApp.Document.QueryFolder.QuerySubFolders(MyFolder) You will also define new Query objects within the Queries collection associated with the new QueryFolder. You will use OriginatingPipe to create the recordsets, and you will apply the ConnectionFilter to the recordset if it exists.

144 Fundamentals of GeoMedia Development Part I

NOTE: This project includes a .res file. This is a compiled VC++ resource file. There are several different types of resources that may be defined in the VC++ project, including bitmaps, strings, and icons. Resource files are an excellent means of externalizing language-specific data. This is important if you are building custom components that you will want to market internationally. Visual Basic supports a number of functions for reading data from the binary file. There is also some runtime advantage to putting this data into a resource file. The items are loaded on demand rather than at form load time, thereby reducing memory costs until the data is actually needed. The VC++ project and files are included in the resdll and include directories. We will not modify these in this lab. You will create a style object for displaying the results of your query. In the GeoMedia user interface, style widths are assigned based on points - a standard printers measurement. Use the following values to determine how to calculate the desired point sizes. Remember, the style width is based on the paper scale of the coordinate system. If your display is greater or smaller than the paper scale, the measurements will not match point size you specified. One point is 1/72 of an inch (0.0139 inches). One point is 0.353 millimeters. When using gmsStyleUnitsPaper, the Width is specified in HIMETRIC units where 100 units is one millimeter. Using the HIMETRIC measurement, 35 units is one point (1/3 of a millimeter).

For example, if you specify 300 units in the Width property, the GeoMedia dialog will display 9 points. At your defined paper scale, the line will measure 3 mm or 1/8 inches. Since this lab involves a very user-interactive task, it includes quite a bit of user-interface handling. Most of this handling is included in the command skeleton so that the lab can focus on manipulation of the GeoMedia objects. To familiarize you with the project, this table describes the files and their contents. Additionally, the last column indicates if you will need to modify the file contents.

File

Description

Methods to modify

Adding Commands to GeoMedia 145

frmCustomReports.frm frmNewFolder.frm

Main form for the command. Form displayed to get information about new folders. Form displayed to get information about new reports. Wizard-generated command class. Wizard-generated functions and globals. Declarations of constants. Performs initialization of the CustomReports form. Contains the subroutine to create the legend entry. Performs initialization of the NewReport form. Contains a subroutine for retrieving the connection filter data. Compiled bitmaps, icons.

None None

frmNewReport.frm

btnOK_Click

CustomReports.cls modCustomReports.bas modGlobals.bas modInitCustom.bas

None None None CreateLegendEntry

modNewReport.bas

InitializeNewReport

CustomReports.res

None

Section A: Getting Started


1. Open the project, C:\TGM\Labs\Lab14\src\GeoMediaCommand.vbp. The project window will appear. 2. Select File > Make CustomReports.dll... to compile the command. Accept ..\bin\CustomReports.dll as the output location. Select Yes when prompted to overwrite an existing DLL. 3. Open a command window, and install the command DLL. Issue the command - "c:\program files\geomedia\program\installusrcmd.exe" CustomReports.dll CustomReports.ini - from the bin directory of the command. 4. Start GeoMedia, and open (or create) a GeoWorkspace. 5. Select Tools > Customize... Select the Menus tab.

6. Select the Map Window type.

146 Fundamentals of GeoMedia Development Part I

7. Select the Custom entry in the Categories list. 8. Select the Custom Reports command from the Commands list. 9. Select &Help entry on the Change what menu list. 10. Select Add. 11. Select the Data Window type. 12. Repeat steps 7 - 10. 13. Select Close. 14. Select and test the command. Only the New button is enabled initially. Select New and the New Folder form will appear. You can test the creation and deletion of folders with the code skeleton. Select Close on the Custom Reports form after you have tested adding and deleting folders. The command will test for duplication of folder names as well. 15. Exit GeoMedia. Summary: In Section A, you used the InstallUsrCmd.exe program to make the custom command available within your GeoMedia environment. This is necessary since you did not run the Command Wizard to create the Visual Basic project. You associated the command to the menus and you can test some of the basic operations including the creation and deletion of folders.

Connections and Metadata


This section of the lab accesses the connection objects and uses the metadata service to get a list of tables from the warehouse. The GeoMedia connection object is a generalized mechanism for accessing different warehouses. Each document can have several connections. The connections collection is the list manager for the warehouses -- GDO servers. Metadata is data about data. That is, metadata describes the characteristics of your data instances. The feature class definition is a form of metadata. GeoMedia also supports additional metadata information that is not part of the GDO table and field definitions. The creation, maintenance, and access to the metadata are controlled through the metadata service. However, since the metadata is stored in the database for read/write servers, you could maintain this information

Adding Commands to GeoMedia 147

without using the service. In this lab, you will use the metadata service to determine the primary geometry field. GeoMedia uses the primary field extensively to know which gdbSpatial field to use for analysis.

Section B: Initializing the Report Form


1. Select modNewReport under the Modules folder in the Project Window and select View > Code. 2. Select the (General) object and the InitializeNewReport procedure. 3. Implement the logic to add all of the connection names to the combobox and select (highlight) the first connection from the list. You will need to iterate over the Documents Connections collection. Pass the ConnectionName from the connection object as the argument to the AddItem method. Be sure that the connection is open before adding it to the list. Setting the ListIndex property to 0 will highlight the first item in the list. 4. Now for the first connection, display all of the feature tables in the list. Use the MetadataService to get the list. Retrieve the first connection object and hold it in the objConn variable. The ProgID for the service is GMService.MetadataService for objMD. Set the Connection property to the first connection. Use the GetTables method passing 0 and vList as the arguments. Again, use AddItem on the list control to display the names. The vList variable will actually contain an array of strings. The last entry is the empty string. UBound and LBound are built-in Visual Basic functions to determine the number of elements in an array. 5. Save and compile your command. 6. Start GeoMedia, open (or create) a workspace, and test your command. Iteratively test your command until you are successfully able to display the populated New Report form. 7. Exit GeoMedia. 8. Return to the Visual Basic project. Select frmNewReport under the Forms folder in the Project Window, and select View > Code. 9. Select the cboConnections object and the Click procedure. 10. Review the code in this section. It is very similar to the section you just wrote. This will update the table list when the end-user changes the connection.

148 Fundamentals of GeoMedia Development Part I

Summary: In Section B, you have processed the Connections collection to populate the list of available connections for only the open connections. You have also used the MetadataService to retrieve the list of features. Although this command supports queries on any feature, you can filter the list of tables based on geometry type by using the mask argument to the GetTables method.

Filtering Queries and Geometry Transformations


In many cases, you will be accessing very large data sets. Although you need the ability to view all data simultaneously, you only need to view a geographic subset of that data. GeoMedia and GDO achieve this by providing a spatial filtering capability. A filter is a geometry that defines an area within the data model. When you create a recordset, you can specify what geometry to use for filtering, how to compare this geometry to the data in the server (inside, overlap), and which data (field) to compare against. As we discussed briefly as we reviewed pipes in GeoMedia, pipes add value to GeoMedia through client-side extensions where GeoMedia is the client. Section C of the lab will use the Name extension to create the query object. Section D of the lab will use the ExtendedPropertySet extension to retrieve metadata information. GeoMedia can display geographic data within a number of different coordinate systems. Each coordinate system will display the data in a slightly different manner. In some cases, the visible characteristics of the data may change radically. As a GeoMedia programmer, you need to be aware of when you need to perform transformations of data and values. Recall that there is a coordinate system associated with the document. This may or may not be the same as the warehouses coordinate system. In this case, GeoMedia transforms the data from the server to a representation appropriate for the documents display. Likewise, when you digitize in GeoMedia, data is collected in the coordinate system of the document. You will need to transform it to the system of the server for storage of geometry data.

Section C: Creating and Saving the Report


1. Return to the Visual Basic project. Select frmNewReport in the Project Window, and select View > Code.

Adding Commands to GeoMedia 149

2. Select the btnOK object, and select the Click procedure. 3. Get the selected connection, and create an OriginatingPipe object. Populate the temporary variable, objConn, with the selected connection. Create the OriginatingPipe object and populate the Table and Filter properties from the values in lstTables and txtFilter. The OriginatingPipe object is created with the CreateOriginatingPipe method on the connection object. 4. Call the subroutine DetermineFilter. This subroutine has already been written. The function signature is Call DetermineFilter( chkFilter.Value, objConn, objOP).. It uses the value of the chkFilter control to determine whether or not to assign the filter to the OriginatingPipe. 5. Retrieve the new recordset from the OriginatingPipe object. Use the objRS variable to hold the OutputRecordset from objOP. 6. Retrieve the Name extension from the recordset. This returns a query object. Populate the query object. Use the GetExtension method requesting the Name object. Set the .Name and .Description properties. 7. Append the query object to the appropriate query subfolder. Remember that strQueryFolder holds the name of the subfolder that will contain this query. Use the Append method on the Queries collection. 8. Save and compile your command. 9. Start GeoMedia and test your command. Select Legend > Add Feature Class Add the States feature. Select Warehouse > Connection Filter Select Define You are prompted to draw a rectangle around some area of data. Double click the mouse to return to the form. 10. Select Close. Select Warehouse > Edit Connection Click in the Connection Filter Name field. Select a filter for this connection. Select Close. Save your workspace. 11. Test your command. Test your command until you are successfully able to define a report. Specify an invalid attribute filter (where clause) to ensure that you get an error message. 12. Exit GeoMedia. 13. Return to the Visual Basic project. Select modNewReport under the

150 Fundamentals of GeoMedia Development Part I

Modules folder in the Project Window, and select View > Code. 14. Select the DetermineFilter procedure. 15. Review the code used to apply the spatial filter to the pipe. The metadata service is used to find the primary geometry field. Since the filter is defined in the coordinate system of the document, we will have to transform it to the server system. We set up the transformation first. If there is a filter associated with the connection and the control was selected to apply the filter, then create a copy of the filter geometry, convert it to the servers coordinate system, and assign the result to the originating pipe SpatialFilter property. Summary: In Section C, you created an OriginatingPipe object based on the users selection of a connection and table and any filter (attribute or spatial) specification. The OriginatingPipe produces an output recordset (internally using GDatabase.OpenRecordset) which provides additional capabilities. These capabilities include support for notification of data changes, access to the metadata for the table, and persistence of the request within the workspace through the Query object. The section also saves the recordset and query object in the appropriate QueryFolder object. You can build your own folder hierarchy to manage predefined queries in your application. Finally, the command includes the logic to apply the connection filter to restrict the query to a particular geographic area. You accessed the SpatialFilter object associated with the Connection and converted this geometry to the coordinate system associated with the data warehouse.

Displaying Data
As you know, all data is displayed in the map window through the legend entries. In order to visualize and distinguish the different features in your model, you need to assign different styles to each legend entry. This is achieved with the use of one of the style objects. You will create a style object and associate it with the legend entry for displaying the results of your query. In the GeoMedia user interface, style widths are assigned based on points a standard printers measurement. The following values help you determine how to calculate the desired point sizes. Remember, the style width is based on the paper scale of the coordinate system. If your display is greater or smaller than the paper scale, the measurements will not match the point size you specified. One point is 1/72 of an inch (0.0139 inches).

Adding Commands to GeoMedia 151

One point is 0.353 millimeters. When using gmsStyleUnitsPaper or gmsStyleUnitsPaperAsNonscaling, the Width is specified in HIMETRIC units, where 100 units is one millimeter. Using the HIMETRIC measurement, 35 units is one point (1/3 of a millimeter).

For example, if you specify 300 units in the Width property, the GeoMedia dialog will display 9 points. At your defined paper scale, the line will measure 3 mm, or 1/8 inches. If you specify gmsStyleUnitsView, the width is the number of pixels. When using gmsStyleUnitsPaperAsNonscaling, the behavior is the same as gmsStyleUnitsView, but the value is calculated from the point size or the HIMETRIC values. Hence, eighteen points will appear as one quarter (1/4) inch on the screen and will disregard the view extents and the coordinate systems paper scale value.

Section D: Running Queries


1. Open the command project. Select frmCustomReports in the Project Window, and select View > Code. 2. Select the btnRun object, and select the Click procedure. Review the code to add the recordset to the active data view. 3. Select frmCustomReports in the Project Window, and select View > Code. 4. Select the btnRun object, and select the Click procedure. 5. Review the logic to create a legend entry. Also review the logic to display the recordset on the map view. In this method, the CreateLegendEntry subroutine is called and the legend entry appended to the map views legend. Once the legend entry is appended, you will call ValidateSource and LoadData to tell GeoMedia to display the data. 6. Select modInitializeCustom in the Project Window, and select View > Code. 7. Select the CreateLegendEntry procedure. 8. Implement the logic to create a legend entry and style object. Assign the style to the legend entry. Create a linear style object. This style can be used to symbolize all data types. Create the legend entry and assign the style to it. Use the

152 Fundamentals of GeoMedia Development Part I

ProgID GeoMedia.RecordLegendEntry to create the legend entry and GeoMedia.LinearStyle, to create the style. Use gmsStyleUnitsPaper for StyleUnits, gmsLinearModeShowBackground for Mode, vbRed for Color, and 300 for Width. Set the Title of the legend entry to the input string. Set the Subtitle to the string Custom Report. Extra Credit: Create a default style based on the geometry type. Additionally, rather than defaulting to red, create a cyclic defaulting scheme for the 16 basic colors (0 - 15). 9. Find the primary geometry field for the recordset. Assign this value to the legend entry. Use the ExtendedPropertySet extension on the recordset to find this information. Retrieve the extension object with the GetExtension method. From this object, use the GetValue method, requesting the PrimaryGeometryFieldName. 10. Create a transform pipe object to transform the primary geometry in the recordset. Associate the recordset with the legend entry. The ProgID for the pipe is GeoMedia.CSSTransformPipe. You will need to populate the InputRecordset with the subroutines recordset argument, the CoordSystemsMgr with the documents coordinate system manager, the InputGeometryFieldName with the name retrieved in step 9, and the OutputCSGUID with the GUID of the CoordSystem object within the Document.CoordSystemsMgr. Assign the OutputRecordset to the legend entry. 11. Save and compile your command. 12. Start GeoMedia and test your command. Test your command until you are successfully able to display the recordset in the map view. Test both an empty legend and one with entries. The new entry should display at the top. 13. Exit GeoMedia. Summary: In Section D, you implemented logic to display the recordset in the map view. A style object is created and associated with the legend entry. The GetExtension method is used to access the metadata to find the primary spatial geometry field. Finally, you transformed the recordset from the coordinate system of the server or warehouse to that of the map view or client.

Adding Commands to GeoMedia 153

Section E: Editing Queries (Extra Credit)


Extend the capabilities of this command to change the criteria of the query and to refresh any existing displays of the data.

154 Fundamentals of GeoMedia Development Part I

Modeless Commands
Modeless commands are the second type of command available in GeoMedia. Modeless commands differ from modal commands in one important aspect: they do not need to be terminated before you can continue working with the rest of the application. While modal commands take over the application until the dialog is closed and the command is completed, modeless commands allow you to shift the focus from a dialog or window to a secondary window -- or even to another command. Unlike modal commands, modeless commands remain active until they receive an event that tells them to deactivate. Modeless commands are not as common as modal commands and are a bit more complex to develop, but there are situations where they are very useful. The Find command in Microsoft Word or Visual Basic is an example of a modeless command that uses a dialog to collect the users search criteria, performs the find operation, and allows the user to move around in the document while the Find command is still active. As a GeoMedia custom command writer, you will find that modeless commands can be employed to handle a variety of scenarios which would be cumbersome or even impossible to do with modal commands alone. The advantage of using a modeless command when developing a custom command in GeoMedia is that it allows user interaction with one of the application windows in the middle of the command. For example, you might want to create a fancy Print Area command that has the user define the boundary of the target area in a map view and then modify the extents dynamically, all the while demonstrating what the new settings are in a modeless dialog. The disadvantages of using a modeless command are that much greater care must be taken to handle all scenarios and to cleanly deactivate the command at the appropriate time. Additionally, you will recall that Visual Basic OLE servers do not support modeless dialogs. As such, you must keep this limitation in mind when developing modeless custom commands. If a command uses a modeless dialog that requires user input on the form (e.g., key-in field), the dialog must be written in VC++.

Types of Modeless Commands


The GeoMedia command wizard creates a VB project with several files in it that serve as a skeleton for a custom modeless command. In the View Listener Command Type step of the command wizard, you are asked to

Adding Commands to GeoMedia 155

select what type of modeless command you want to create. Recall the four types of modeless commands: Select commands -- (e.g., feature selection) only one command from this group may be listening to map views at a time. A new listener from this group will terminate any existing listener if termination is allowed by the old listener. Placement / Edit commands -- (e.g., place new feature / modify feature geometry) - only one command from this group may be listening to map views at a time. A new listener from this group will terminate any existing listener if termination is allowed by the old listener. This selection will suspend any command in the Selection group. View change / Define sub-view commands -- (e.g., zoom in / print area or snapshot) - only one command from this group may be listening at a time. A new listener in this group will cause any command in the Selection or Placement/Edit groups to temporarily stop listening to events until the command in this group completes. Tracker commands -- (e.g., scale bar, north arrow, mouse data point readout, etc.) - any number of these commands may be listening at a view. Listeners in this group are not affected by the other groups.

Modeless Command Class Methods


The life cycle of a modeless command is cleanly divided into two phases: set up (modal) phase and listening phase. During the setup phase, the command may create new modeless windows and/or start listening to events at existing windows; then the command returns control to the application. After the overall application is released to respond to events, the command is still active and moves into the second phase, where it listens for events at the windows that it created or attached to until an event is received that signals it to end. One of the generated files from the GeoMedia command wizard is a command class module (.cls file) that consists of the methods listed below. Following is a brief summary of these methods: Initialize - This is the first method that is called after the command is selected from the menu. This routine is called only once no matter how many times the command is re-executed. In it, the EventServer object is created and the form with the EventControl on it is loaded. You can add any code to this method that you want to execute only the first time the command is run. Activate - This method is executed each time the command is run and is the core of the command setup phase mentioned above. First the

156 Fundamentals of GeoMedia Development Part I

IsDone property is set to False; and if your command has an initial modal dialog that is used to gather user input, it will be displayed here. After this dialog is dismissed, the command is registered with the view listeners manager. This component enforces the command stacking rules and determines if the command will terminate when another command is started (see previous section). Also in this routine, the EventControl is attached to the EventServer for each map view that it wants to receive events from, registering itself as a listener to the map view. Each view that is being listened to is added to a private collection that is used later. In this routine you will add any initialization code for the modeless command that you need to run each time the command is executed. CanActivate - All command servers that are custom map view listeners must implement this method. The method is called before the Activate method. A custom modeless command is one that is not categorized in one of the four types of modeless commands described in the previous section. Normally this simply returns a status of True. Deactivate - This is called when a modeless command receives an event to stop execution. At this time, the IsDone property is set to True, all map view listeners are disconnected from the EventServer, and each map view is removed from internal collection. In this method you will add code to clear memory of any objects used in the Activate method or objects from the form module. AddView - This method is used to register a map view so that you may begin to listen to events received by the command using the EventControl. RemoveView - This method does the inverse of the AddView method by unregistering a view from the event-listening process. IgnoreEvents - If another command is started in the middle of the current modeless command, then this method will be called so that the map view will be temporarily disconnected from the EventControl. This allows the events to be handled correctly by the interrupting command. RestoreEvents - After an interrupting command is completed, the map view will be reattached to the EventControl, and it will proceed again listening to events in that view. Terminate - This is called when the command manager is shutting down, normally when you select the File > Exit command. As a result, this method is executed only once in a command life cycle. At

Adding Commands to GeoMedia 157

this time, you will add any extra memory cleanup, especially of objects created in the Initialize method.

Lab 15: Magnify View


In this exercise, you will create a modeless command that displays a small Magnify window with the contents of a portion of the active map window zoomed in at a smaller scale so as to look bigger. A small square is drawn in the map view centered around the cursor showing the extent of the Magnify window. You are able to move the mouse around the active map window, and the contents of the Magnify window will change accordingly. Likewise, you are able to execute any view change command (e.g., zoom in) and the Magnify window will respond appropriately. The command can be terminated by one of four ways: Press the ESC key at any time. Cancel the Magnify window by pressing the x in the upper right corner of the Magnify window. Move the cursor into the Magnify window map view area. Exit the application.

The GeoMedia components used in this lab are:

Components MapView GeometryEditService PointGeometry RectangleGeometry LinearStyle EventControl

Type Library MapviewLib PClient PBasic PBasic PView GMEventControlLib

The command was created with the wizard as a modeless, map view listener in the tracker group. The enabling conditions require an active map view and open connection. One of the related objects used in the form module of Lab 15 is the

158 Fundamentals of GeoMedia Development Part I

MapViewDispatch pointer, which is used as a variable passed into the event control methods. It refers to the IDispatch interface on the map view object. As you may recall from the Automation Overview discussion, interfaces are the means by which you communicate with an object; and an object may have one or more interface pointers. The IDispatch interface is a specific interface that all automated objects support which allows you to access all the automation methods of that object. The IDispatch interface communicates all the public methods and properties of the object to the automation client. Another object referenced in this lab is the CommandClass. Each command in GeoMedia is a separate OLE automation server which supports one interface - the command interface. The CommandClass pointer refers to this interface, which in this case consists of the methods defined in the Magnify.cls file. The CommandClass object is used in this lab so that the methods in the class module can be called from the form module. To familiarize you with the project, this table describes the files and their contents. Additionally, the last column indicates if you will need to modify the file contents.

File frmMagnify.frm

Description Main form for the command (it is hidden)

Methods to modify Form_Load Form_Unload EventControl1_KeyUp EventControl1_MouseMove SetCmdCls SetMapViewDispatch UnsetMapViewDispatch ResetGeometryEditService

Magnify.cls

Wizard generated command class

Initialize Activate Deactivate RemoveView Terminate

modMagnify.bas

Wizard generated functions and globals

None

Adding Commands to GeoMedia 159

In addition to the modeless command class methods discussed above, you will need to add code to several subroutines in the form module in order to complete this lab. There are two routines that are triggered when events are received by the EventControl. In the frmMagnifys EventControl1_KeyUp subroutine you will write code to handle the case when the user hits the Esc key. Likewise, in the frmMagnifys EventControl1_ MouseMove routine you will handle the case when the user moves the mouse around the map view. The frmMagnifys Form_Load and frmMagnify.Form_Unload subroutines are executed when the command is initialized and terminated, respectively. Using the generated source code from the command wizard as a starting point for developing this command, you only need to add a limited amount of code in order to complete it. However, care should be taken to carefully remove any allocated memory by setting any object variable to nothing after you are done using the object. As is true with other custom command development, failing to clear memory in a modeless command can lead to strange behavior and unexpected crashes.

Section A: Creating the Magnify Window


1. Start Visual Basic, opening the command skeleton for the Magnify modeless command. The project is located in C:\TGM\Labs\Lab15\src. 2. Select View > Code on the Magnify.cls file under the Class Modules folder in the Project Window, and select the Activate method. 3. Create a new window. You will need to use the NewMapWindow method of the Document object. The newly created window will become the ActiveWindow. 4. Give the new window the title Magnify. Use the Caption property on the map (Active) window. This caption will be used to identify this window in several places later. The constant MAGNIFY_CAPTION is available for use. 5. The command already sets the dimensions of the Magnify window to be a square window that is 1/3 the size of the smallest dimension of the application. The applications Height and Width properties are used in the calculation and the resulting values are used to set the Height and Width of the Magnify window. 6. Position the Magnify window in the lower right of the application.

160 Fundamentals of GeoMedia Development Part I

Set the Top and Left properties of the Magnify window. Remember that these two properties are relative to the application window (not the screen) so that 0,0 is the upper-left corner of the application. You will have to account for the statusbar height (subtracting it from the Application.Height) in the calculation for the Top as well as the application frames width (subtracting it from Application.Width) in the Left calculation. Use the variables, lStatusbarHeight and lFrameWidth, in the calculation. 7. Exit the command if all the views that the MapViewListener is listening to have been removed. At the end of the RemoveView subroutine, there is a check to see if all the views have been removed (Count=0). If they have, then add a call to Deactivate in the If - Then clause. 8. Save the project and compile the custom command. Select File > Make Magnify.dll... 9. Register the command. This is necessary since you did not use the Command Wizard to create the initial command on this machine. You need to open a command window and move to the c:\TGM\Labs\Lab15\bin directory. Execute the command: "c:\Program Files\GeoMedia\Program\Installusrcmd.exe" Magnify.dll Magnify.ini Start GeoMedia and add the new Magnify command to the menus using Tools > Customize Follow the steps in Lab 13 to add a custom command to GeoMedia. 10. Run the Magnify command. Confirm that the Magnify window displays in the lower right corner of the application as a square window with the correct caption. If necessary, modify the calculation for the Top, Left, Height, or Width properties of the Magnify window, and rerun the command until the new window is sized and position correctly. Note: Because we have not added code to make the command reentrant, you may only be able to run it once - the second invocation of the Magnify command may cause a crash.

Adding Commands to GeoMedia 161

Summary: In Section A, in addition to installing the command skeleton, you created a new map window and set its Caption, Height, and Width properties. You also established the position of the window in the lower right corner of the application framework. You successfully associated the command to a GeoMedia menu. When you select your command, a new, empty map window will appear. Finally, you triggered the command to Deactivate when all the views were closed that it was listening to.

Section B: Populating the Magnify Window


1. Return to Visual Basic, and edit the Activate method in Magnify.cls. 2. Create a copy of the legend of the active map view. Use the Copy method on the Legend object. It is probably easiest to do this before the Magnify window is created and while the active window is still the map window. The active window contains the features we want to magnify. Use the variable objMagnifyLegend to hold the copy. 3. The variable, objMagnifyMapView, has been declared. It will be used throughout the exercise and contains the Magnify map view. 4. Set the legend in the Magnify map view to be the same as the active map window. Assign the object, objMagnifyLegend, from Step 2 as the Magnify legend. Note: This must be done after the Magnify window has been created. Use the variable declared in the Step 3 with the Legend property. 5. The command sets the Visible property of the legend to False. This turns off the display of the legend in the Magnify window. 6. Loop through the legend entries in the Magnify legend, and load each entry into the Magnify window. Create a For loop, and call the LoadData method on each entry. 7. Modify each legend entry in the Magnify window so that the graphic features cannot be selected. Set the Locatable property on each legend entry in the same loop as Step 6. 8. Close the Magnify window. At the end of the Deactivate method use the Close method on the Magnify map window. Since the variable objMagnifyView contains a pointer to the mapview control, you will need to traverse to the window

162 Fundamentals of GeoMedia Development Part I

through the Parent property. 9. Compile the command. 10. Test the Magnify command in GeoMedia. The Magnify window will still be empty at this point. Execute a mouse right click in the Magnify window and check the Legend option. The legend should display with the same legend entries as the map view (the one that was active when the Magnify command was started). The legend entries should be loaded, and the legend should look identical to the map view legend. If you have not released all of the global variables, the command may crash on exit. Summary: In Section B, you created a copy of the legend from the active map view and associated it with the Magnify window. You implemented the logic to display the geometry data with the legend entry LoadData method. You also indicated that none of the data in the Magnify window could be located with the mouse by setting the Locatable property to False for each legend entry. Finally, you closed the Magnify window.

Section C: Drawing a Square Cursor and Tracking Mouse Events


1. In the Visual Basic project again, use View > Code to edit the frmMagnify.frm file. 2. The command defines four variables at the top of the form module that correspond to: a GeometryEditService object (objGeomEditSrvc) a RectangleGeometry object (objRectangle) a LinearStyle object (objRectangleStyle) a PointGeometry object (objPoint)

3. Create the objects in the Form_Load subroutine using the App.CreateService method. The App.CreateService directive is used rather than the CreateObject method to instantiate each of these objects because we will be doing some debugging and we want to create all of the objects in the same process space. See the article in the Programming Caveats section of the Appendix for more information on this topic.

Adding Commands to GeoMedia 163

4. Initialize the style of the rectangle to black with a weight of 3. Do this also in the Form_ Load routine immediately after creating the rectangle object. Use the LinearStyle object and set the BackColor and BackWidth properties. Black is defined as a color having a value of 0. 5. Set the map view on the GeometryEditService object. Use the public subroutine (called SetMapViewDispatch) that has one argument which is a map view dispatch pointer. In this subroutine you will assign the subroutines argument holding the map dispatch pointer to the MapView property of the GeometryEditService object. 6. Add code so that each time the command is run, the GeometryEditService has the correct MapView property. You will now edit the Activate method in the Magnify.cls file and call the subroutine created in Step 5. Dont forget to pass the map view dispatch pointer of the right window (the original active map window when the Magnify command was called). 7. Before drawing the box around the cursor, you need to make sure no other temporary graphics are displayed. In the form module, edit the MouseMove method of the EventControl. Use the RemoveAllGeometries method on the GeometryEditService object to clear it. 8. The command retrieves the Height and Width of the map window and stores them in the variables: lx2Win and ly2Win. You will use these values to calculate the size of the square round the cursor. 9. The command next determines the dimension of the window in world coordinates. This calculation converts window coordinates (0,0 being the top/left of the window) into world coordinates using the WindowToWorld method on the map view. By determining the size in world coordinates, you avoid the discrepancies that may occur with different coordinate systems. The smaller dimension is chosen and stored in the variable dblMinWidth. It is important that the width be in world coordinates since you want to use this to determine the extents of the magnify window. 10. Calculate the height and width of the rectangle around the cursor. Divide the value from the previous step, dblMinWidth, by 10. Assign this to the Height and Width of the objRectangle. 11. Calculate the origin of the box that will be drawn around the cursor. Set the origin (use the temporary variable objPoint) of the

164 Fundamentals of GeoMedia Development Part I

RectangleGeometry object (X, Y, Z properties) from Step 2 equal to the worldX, worldY, and worldZ arguments that are passed to the subroutine. Modify the values to offset them by 1/2 the width of the square so the cursor point is directly in the middle of the box. 12. Draw the box around the cursor. Use the AppendGeometry method on the GeometryEditService object. You need to pass the rectangle (objRectangle) and the style (objRectangleStyle) objects. 13. Complete the subroutine, ResetGeometryEditService, to empty the GeometryEditService object before exiting. At the end of frmMagnify module, complete the public subroutine that removes all geometries from the GeometryEditService object and sets the MapView property to nothing. 14. Call the subroutine, ResetGeometryEditService, in the Deactivate method so that it is executed right before the command exits. 15. Compile the project. and test the Magnify command in GeoMedia. You should see a dark, square block around the cursor that tracks with any mouse movement and repaints cleanly in the map view. If you have not released all of the global variables, the command may crash on exit. Summary: In Section C, you created objects to manage the box positioned around the cursor in the view you are magnifying. This included the GeometryEditService for the dynamic display of the geometry, the RectangleGeometry, and the LinearStyle for symbolizing the rectangle. We used the Dispatch property of the map view to establish the communication link between the view and the GeometryEditService. You managed the size and position of the box around the cursor in the MouseMove event. The Height and Width of the box (RectangleGeometry) is determined by the size of the window while the position is determined by the cursor location.

Section D: Magnifying Features


1. Return to the VB project. The variable, objMagnifyViewDispatch, at the top of the frmMagnify module represents the map view dispatch of the Magnify window.

Adding Commands to GeoMedia 165

2. Get the map view dispatch pointer of the Magnify window. Update the subroutine, SetMapViewDispatch, logic to retrieve this pointer. Create a loop that cycles through the collection of windows in the application, and look for the one that has the caption Magnify. Use the MAGNIFY_CAPTION constant. Once it is found then assign its dispatch pointer to the variable defined above in step 1. Remember that we will use the map views Dispatch property to establish communication between the map view and other controls. 3. Now you will calculate the extents of the area to magnify. Get the upper left and lower right corners of the RectangleGeometry object around the cursor. In the MouseMove method for the EventControl in frmMagnify, calculate the six values that correspond to the X, Y, Z coordinates of the two opposite corners in the square box (upper left and lower right). The Origin of the rectangle is the upper left. 4. Draw the graphical features displayed inside the box of the active map view in the Magnify view in a magnified scale. Use the ZoomArea method of the Magnify map view dispatch object, and pass it the six points calculated in the previous step. 5. Update the Magnify window. Call the Refresh method on the Magnify map view. 6. The command includes the appropriate logic to release the map views Dispatch pointer in the UnsetMapViewDispatch subroutine. 7. Call the cleanup routine (UnsetMapViewDispatch) from the Deactivate method. Add a line at the end of the Deactivate method of the command class (Magnify.cls) that calls the subroutine created in the previous step. 8. Compile the project. 9. Test the Magnify command in GeoMedia. You should now see the features from the active map view display in the Magnify window, only much larger. Move the mouse and different magnified elements will display. If you have not released all of the global variables, the command may crash on exit.

166 Fundamentals of GeoMedia Development Part I

Summary: In Section D, you utilized the ZoomArea method of the map view to set the viewing location for the magnify window. The area is defined by the upper left and lower right corners of the box in the window you are magnifying. Logic is also added to release the pointer to the map view dispatch pointer to ensure correct reference counting.

Section E: Exiting the Command Cleanly


1. Return to the VB project. The command includes a variable in the frmMagnify module that represents a pointer to the command class -objCmdCls. This will be used to call methods on the command. 2. Assign the command class pointer. Complete the subroutine, SetCmdCls, in frmMagnify that takes as an argument an Object pointer and assign this to the variable defined in the previous step. 3. Let the form module know at the start of the command the address of the command class. At the end of the Initialize method of the Magnify.cls file, add a line that calls the subroutine, SetCmdCls. Remember, you can pass the variable Me as the command class pointer. 4. So that the command may be terminated, you will add code to check to see if the user pressed the Esc key. In the form module, open up the KeyUp method for the EventControl and add a test for the Esc key (KeyCode = 27). You may also use vbKeyEscape to compare the value. Call the Deactivate method on the command class object assigned in Step 2 above. 5. Clean up the command class pointer on exit. Set the variable defined in the first step of this section, objCmdCls, to Nothing in the Form_Unload method of the form module. 6. Add the Magnify window to the windows that the EventControl is listening to. This is important, because you will not capture the Esc keyin unless you are listening to that window. In the Activate method of the command class, add a call to AddView and pass it the ActiveWindow, which is now the Magnify window. Remember that AddView is a method on the command class. 7. Add a statusbar message to indicate that ESC is a valid key-in to

Adding Commands to GeoMedia 167

terminate the command. Modify the Activate method of the command class and use the SetStatusBar method of the application to indicate in the second pane that ESC is a way to kill the command. 8. End the Magnify command if you move the cursor into the Magnify window. An error handler section has been defined in the MouseMove method of the EventControl before the call to ZoomArea. If there is a problem with the ZoomArea, then it will fall through to the error handler. Add a call to the Deactivate method of the command class. Whenever you move the cursor into the Magnify view, an error will be raised by ZoomArea and the command will end. Alternatively, a more deterministic way to handle this situation would be to calculate at the top of the MouseMove method if the cursor is in the Magnify window by comparing the cursor x,y with the window coordinates and from there calling Deactivate if it falls in the window. 9. End the command if you close the Magnify window by selecting the x button in the top right corner of the Magnify window. The command defines a private variable in Magnify.cls that is a flag indicating whether or not the window is destroyed by the selection of the X on the window bar. This boolean variable, bKillMagWin, will be used in later steps. 10. Initialize the kill window flag. Set the variable, bKillMagWin, to False in the Activate method. 1. Set the kill window flag to True if the Magnify window is closed with the x button. The RemoveView method will be called when the x button is selected and the MapViewListener is removed for that window. Inside the For loop of this routine add an If statement that checks to see if the Magnify window is the one being removed. You can do this by looking at the window caption. If it matches, then set the kill flag to True. 2. Deactivate the command if the kill window flag is True. This is accomplished at the end of the RemoveView routine. The If statement checks to see if the kill window flag is True. If it is, then it calls Deactivate. 3. Do not issue the Close command to the Magnify window if it has already been manually closed. In the Deactivate method, this is accomplished with an If statement before Close method is called.

168 Fundamentals of GeoMedia Development Part I

4. Compile the command. 5. Test the Magnify command in GeoMedia. You should now have a fully functional, modeless Magnify command. Finally, the command will not cause the application to crash on exit. Summary: In Section E, you established a reference to the command class. This provides access to the command from functions and subroutines in the DLL but not within the class module. You trapped the ESC key to Deactivate the command. The applications status bar is updated with a prompt. You added logic to terminate the command when the Magnify window is closed.

Adding Commands to GeoMedia 169

Summary
The overall objective of this section was to familiarize you with the creation of GeoMedia commands. To this end, you learned the purpose and use of the Command Wizard. You now understand the types of GeoMedia commands that may be created: View change / Subview definition Placement / Editing Selection Tracker

You should be familiar with the command stacking capabilities that allow commands within different classes to interrupt or pause other commands. You have also successfully implemented three commands. The first one exercised the command manager and the process of establishing a menu item for the command. The second command utilized the following objects: QueryFolder Query OriginatingPipe SpatialFilter LinearStyle RecordLegendEntry GeometryStorageService ServerTransService CSSTransformPipe ExtendedPropertySet MetadataService

Finally, the third command utilized the following objects: EventControl, EventServer GeometryEditService RectangleGeometry, PointGeometry

170 Fundamentals of GeoMedia Development Part I

You practiced these techniques in the lab: Receiving events Terminating modeless commands Monitoring selective views Temporary geometry construction Legend copying Creating persistable recordsets Manipulating the query folders Associating a spatial filter with a recordset Coordinate transformation operations Retrieving metadata information Displaying data in the map view and data view

The next section will utilize the GeoMedia objects in a custom application. Custom applications are the second approach to GeoMedia customization.

Adding Commands to GeoMedia 171

Can You Answer These Questions?


1. What two types of commands are available in GeoMedia? 2. What restrictions exist for modeless commands? 3. What is the significance of CreateService? 4. What are the two types of collections? Provide a GeoMedia example of each. 5. How do you register a command? 6. How do you remove a command? 7. What is a connection filter? Give an example of its benefit and usage. 8. What two components are used in conjunction with CoordSystemsMgr to transform a recordset from the server projection to the map views projection? 9. What is wrong with this? Set objQuery = gobjGeoApp.QueryFolder.QuerySubFolder(3).Query(4)

172 Fundamentals of GeoMedia Development Part I

Appendices
Document Conventions
Keywords
Italics are used in the workshop text to indicate special objects or keywords.

Definitions
IMPORTANT: Highlights important notes and definitions.

Code Fragments
Indicates a fragment of code

Step by Step Instructions


1. Step one... System prompts and expected results are shown following the corresponding step. 2. Step two...

GUI Indicators
Operations or titles of user interface items (GUI) will be indicated in Bold.

173

174 Fundamentals of GeoMedia Development Part I

Reference Materials
The following materials have been used as reference materials in the creation of this workshop.

Microsoft Development Library


Copyright 1992 - 1996 Microsoft Corporation

Inside OLE 2
Copyright 1995 by Kraig Brockschmidt ISBN 1-55615-843-2

Microsoft Excel Version 5.0 for Windows NT


Copyright 1985 - 1994 Microsoft Corporation, On-line Help

GeoMedia Help
GeoMedia Help Topics Programming with GeoMedia GeoMedia Automation Programming Help Copyright 1997 Intergraph Corporation 1997

Team GeoMedia Technical Articles and Samples


http://www.ingr.com/geomedia/team_geo.htm

Visual Basic 4 Enterprise Development


Copyright 1996 by Que Corporation Craig Goren, James Schmelzer, Jeffery Smith ISBN: 0-7897-0099-9

Object-Oriented Modeling and Design


Copyright 1991 by Prentice-Hall, Inc.

Appendices 175

James Rumbaugh, Michael Blaha, William Premerlani, Frederick Eddy, William Lorensen ISBN: 0-13-629841-9

Where to Get Help


Questions on GeoMedia and GeoMedia customization can be directed to Intergraph support. Our web page provides all the necessary instructions for logging worksheets. Access to our knowledge base is also available for helping you resolve any problems you might have. The web site is: http://www.ingr.com/iss/products/mapping/services/support.htm or http://www.ingr.com/iss/products/mapping/services/GeoMedia.htm Or, you may call 1-800-633-7248 in the US. For non-US customers, please contact your local Intergraph office.

176 Fundamentals of GeoMedia Development Part I

Lab Exercises
The lab exercises are intended to reinforce the concepts presented in the workshop materials. Each lab will start from a skeleton, or template. This template provides you with hints for writing the proper code for the lab. Additionally, much of the code needed to manipulate the GUI will be included in the template. The Labs directory contains the standard templates. These templates provide the code for the exercise, with methods and properties missing as indicated by question marks (??). You need only fill in the missing names. The templates can be found on the floppy labeled Fundamentals of GeoMedia Development Part I Lab Exercises and Solutions, which accompanies the workshop materials. Create a root directory, like C:\TGM. Unzip the templates and solutions to this root directory. The labs are defined in the subdirectory Labs, while the solutions are provided in Solutions. Each skeleton is contained in a subdirectory of (e.g., C:\TGM\Labs\Lab14). Each solution is in a parallel subdirectory of Solutions (e.g., C:\TGM\Solutions\Lab14).

Appendices 177

Feature List for Lab 14


This table provides a list of all the features and their field names and types. This information will be used in Lab 14. Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Airports Cities Cities Cities Cities POINTID FEATURID FAC_TYPE FAC_NAME CITY COUNTY STATE STFIPS FAA_REGION FAC_USE JOINT_USE OWN_TYPE OWN_NAME ELEVATION CDB_DIST RUN_NUM PAD_NUM CONG_LVL LNG_FLT AC_TYPE GEOMETRY TEXT GEOMETRY CITY_NAME POP WHPOP gdbDouble gdbText gdbText gdbText gdbText gdbText gdbText gdbText gdbText gdbText gdbText gdbText gdbText gdbLong gdbDouble gdbInteger gdbInteger gdbText gdbText gdbText gdbSpatial gdbGraphic gdbSpatial gdbText gdbDouble gdbDouble

178 Fundamentals of GeoMedia Development Part I

Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Cities Counties Counties Counties Counties Counties Counties Counties Counties Counties Counties Counties

BLKPOP HISPPOP ASIANPOP MEDAGEMAL MEDAGEFEM ED_LT_HS EDHS EDSOMCOL EDCOL EDGRAD SQMILES TOTCRIME AVETEMP ANNULRAIN ANNULSNOW STATE_NAME CITY_ID POP_EDU FIPS STATE_NAME Geometry POP WHPOP BLKPOP HISPPOP ASIANPOP MEDAGEMAL MEDAGEFEM ED_LT_HS

gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbText gdbLong gdbDouble gdbText gdbText gdbSpatial gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble

Appendices 179

Counties Counties Counties Counties Counties Counties Counties Counties Counties Counties Counties Interstates Interstates Interstates Interstates Interstates Rivers Rivers Rivers Rivers Rivers Rivers Rivers StateNameLabels StateNameLabels States States States States

EDHS EDSOMCOL EDCOL EDGRAD SQMILES TOTCRIME AVETEMP ANNULRAIN ANNULSNOW COUNTY_ID POP_EDU STATE_FIPS STATE_NAME SUB_REGION Geometry Id TYPE RIVER_TYPE STATE_FIPS STATE_NAME SUB_REGION Geometry Id ID LabelColumn FIPS STATE_NAME STAABBRV Geometry

gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbLong gdbDouble gdbInteger gdbText gdbText gdbSpatial gdbLong gdbInteger gdbText gdbInteger gdbText gdbText gdbSpatial gdbLong gdbLong gdbGraphic gdbText gdbText gdbText gdbSpatial

180 Fundamentals of GeoMedia Development Part I

States States States States States States States States States States States States States States States States States States States

POP WHPOP BLKPOP HISPPOP ASIANPOP MEDAGEMAL MEDAGEFEM ED_LT_HS EDHS EDSOMCOL EDCOL EDGRAD SQMILES TOTCRIME AVETEMP ANNULRAIN ANNULSNOW STATE_ID POP_EDU

gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbDouble gdbLong gdbDouble

Appendices 181

Visual Basic Syntactical Constructs


Declarative and Assignment Statements
You declare a variable with the following statement. {Dim | ReDim | Static | Private | Public} variablename [As type]

You declare an object variable in the same way you declare other variables. The only differences are the optional New keyword and the class argument which takes the place of the type. {Dim | ReDim | Static | Private | Public} variable As [New] class Arrays are declared and referenced with their subscripts in parentheses. {Dim | ReDim | Static | Private | Public} arrayname(subscripts) [As type]

Likewise, parentheses are used to numerically index collections. Additionally, most collections allow you to index or address a member of the collection by name.

collection("name") collection!name

-or

Determining the type of an object variable may be accomplished in one of two ways. An expression of the form TypeOf objectname Is objecttype may be used as the condition in decision or loop structures. The TypeName function may be used in an expression. It returns a string containing the object type. Dim strObjectType As String strObjectType = TypeName(objectname)

You assign the value of an expression to a variable or property as:

182 Fundamentals of GeoMedia Development Part I

[Let] varname = expression Explicit use of the Let keyword is a matter of style, but it is usually omitted.

You often need to make several property assignments or perform several different actions on the same object. You can do this with the With statement. With object .property = expression .method(arguments) . . End With -and/or-

You assign an object to an object variable with the Set statement: Set variable = object After you declare an object variable, you must assign an object reference to the variable before you can use the objects properties, methods, and events. You can assign a new object reference in several ways.

If you declared the variable using the New keyword, Visual Basic will automatically assign a new object reference the first time you use the variable. You can assign a reference to a new object in a Set statement by using the New keyword or CreateObject function. Set objectvariable = New class Set objectvariable = CreateObject("progID") -or-

You can assign a reference to a new or existing object in a Set statement by using the GetObject function.

When you are finished using an object, clear any variables that reference the object so the object can be released from memory. To clear an object variable, set it to Nothing.

Appendices 183

Set objectvariable = Nothing

Procedural Structures
A Sub procedure is a block of code that can take arguments, perform a series of statements, and change the value of its arguments. [Private|Public][Static]Sub procedurename (arguments) [statementblock] [Exit Sub] [statementblock] End Sub You call a Sub procedure as a stand-alone statement in one of two ways:

procedurename arguments
Call procedurename(arguments)

-or-

A Function procedure is a block of code that can take arguments, perform a series of statements, change the value of its arguments, and can return a value to the calling procedure. [Private|Public][Static]Function procedurename (arguments) [As type] [statementblock] [Exit Function] [statementblock] End Function You call a function by including the function procedure name and arguments on the right side of a statement or expression.

returnvalue = function(arguments)

Decision Structures
Use an If...Then structure to execute one or more statements conditionally. You can use either a single-line syntax or a multiple-line block syntax.

184 Fundamentals of GeoMedia Development Part I

If condition Then statement If condition Then statements End If

Use an If...Then...Else block to define several blocks of statements, one of which will execute. If condition1 Then [statementblock-1] [ElseIf condition2 Then [statementblock-2]] ... [Else [statementblock-n]] End If

A Select Case statement provides capability similar to the If...Then...Else statement, but it makes code more readable when there are several choices. Select Case testexpression [Case expressionlist1 [statementblock-1]] [Case expressionlist2 [statementblock-2]] . . . [Case Else [statementblock-n]] End Select

Loop Structures
Use a Do loop to execute a block of statements an indefinite number of times. In the Do While...Loop, the statements execute as long as the condition is True. Do While condition [statementblock] [Exit Do]

Appendices 185

[statementblock] Loop

In the Do Until...Loop, the statements execute as long as the condition is False. Do Until condition [statementblock] [Exit Do] [statementblock] Loop

When you know you must execute the statements a specific number of times, use a ForNext loop which uses a variable called a counter that increases or decreases in value during each repetition of the loop. For counter = start To end [Step increment] [statementblock] [Exit For] [statementblock] Next [counter] The arguments counter, start, end, and increment are all numeric.

A For Each...Next loop repeats a group of statements for each element in a collection of objects. For Each object In collection [statementblock] [Exit For] [statementblock] Next object

186 Fundamentals of GeoMedia Development Part I

Visual Basic Notation Conventions


Introductory Remarks
Some of the content below is based on information available through Visual Basic Books Online and MSDN. It is convenient for the programmer to be able to determine the data type of a variable or constant quickly and directly from the name. To this end, programmers use notation conventions; perhaps the most famous is the socalled Hungarian notation convention, developed by Charles Simonyi. The exact notation convention used within a given Visual Basic program is not as important as that one is used throughout. Typically, the first few (1-4) letters indicate what data type a variable or constant is. This prefix is usually in lower case letters, and the following letter is capitalized in the variable name. For example, the variable supplied by the GeoMedia Command Wizard for the GeoMedia application object is named: gobjGeoApp Here, g refers to the fact that gobjGeoApp is a global variable, and obj refers to the fact that gobjGeoApp is an object. An example of a GeoMedia constant is gmsqTouches Here gm stands for GeoMedia, sq for Spatial Query, and Touches is the particular spatial operator referred to. The other GeoMedia Spatial Query constants have similar names, e.g., gmsqEntirelyContains. Before getting into a discussion of general Visual Basic conventions, we wish to note two characteristics of GeoMedia objects. The first is that many times a property of a GeoMedia object corresponds to a GeoMedia object. For example, the Application object has a property called Document which is in fact a Document object. An example of a property on a Document object is Name. Thus, gobjGeoApp.Document.Name makes good sense, just as objDocument.Name does if objDocument is a Document object.

Appendices 187

Secondly, we wish to note a convention regarding collections; we illustrate by looking at the Connections collection off of the Document object. Generally speaking, collections are named with the plural of whatever they are collections of. Thus, objDocument.Connections is a Connections object, which is a collection of Connection objects. Thus, objDocument.Connections(3) is a Connection object; in fact, it is the third Connection object in the Connections collection of objDocument.

Variable Scope Prefixes


We now begin with an excerpt from Visual Basic Books Online, located at: Start Here Programmers Guide (All Editions) Visual Basic Coding Conventions Constant and Variable Naming Conventions As a project size grows, so does the value of recognizing variable scope quickly. A one-letter scope prefix preceding the type prefix provides this without greatly increasing the size of variable names.

Scope Global Module-level Local to procedure

Prefix g m
None

Example
gstrUserName mblnCalcInProgress dblVelocity

A variable has global scope if it is declared Public in a standard module or a form module. A variable has module-level scope if declared Private in a standard module or form module, respectively. Note Consistency is crucial to productive use of this technique; the syntax checker in Visual Basic will not catch module-level variables that begin with "p."

188 Fundamentals of GeoMedia Development Part I

Suggested Prefixes for Controls To address naming of controls and DAO objects, we now quote from: Start Here Programmers Guide (All Editions) Visual Basic Coding Conventions Object Naming Conventions

ControlType 3D Panel Animated button Check box Combo box Command button Common dialog Communications Control (used within procedures when the specific type is unknown) Data control Data-bound combo box Data-bound grid Data-bound list box Directory list box Drive list box File list box Form Frame Gauge Graph Grid

Prefix pnl ani chk cbo cmd dlg com ctr

Example pnlGroup aniMailBox chkReadOnly cboEnglish cmdExit dlgFileOpen comFax ctrCurrent

dat dbcbo dbgrd dblst dir drv fil frm fra gau gra grd

datBiblio dbcboLanguage dbgrdQueryResult dblstJobType dirSource drvTarget filSource frmEntry fraLanguage gauStatus graRevenue grdPrices

Appendices 189

Horizontal scroll bar Image Key status Label Line List box MAPI message MAPI session MCI MDI child form Menu MS Flex grid MS Tab OLE Outline Pen BEdit Pen HEdit Pen ink Picture Picture clip Report Shape Spin Text box Timer UpDown Vertical scroll bar Slider ImageList TreeView

hsb img key lbl lin lst mpm mps mci mdi mnu msg mst ole out bed hed ink pic clp rpt shp spn txt tmr upd vsb sld ils tre

hsbVolume imgIcon keyCaps lblHelpMessage linVertical lstPolicyCodes mpmSentMessage mpsSession mciVideo mdiNote mnuFileOpen msgClients mstFirst oleWorksheet outOrgChart bedFirstName hedSignature inkMap picVGA clpToolbar rptQtr1Earnings shpCircle spnPages txtLastName tmrAlarm updDirection vsbRate sldScale ilsAllIcons treOrganization

190 Fundamentals of GeoMedia Development Part I

Toolbar TabStrip StatusBar ListView ProgressBar RichTextBox

tlb tab sta lvw prg rtf

tlbActions tabOptions staDateTime lvwHeadings prgLoadFile rtfReport

Suggested Prefixes for Menus


Applications frequently use many menu controls, making it useful to have a unique set of naming conventions for these controls. Menu control prefixes should be extended beyond the initial "mnu" label by adding an additional prefix for each level of nesting, with the final menu caption at the end of the name string. The following table lists some examples.

Menu caption sequence File Open File Send Email File Send Fax Format Character Help Contents

Menu handler name mnuFileOpen mnuFileSendEmail mnuFileSendFax mnuFormatCharacter mnuHelpContents

When this naming convention is used, all members of a particular menu group are listed next to each other in Visual Basics Properties window. In addition, the menu control names clearly document the menu items to which they are attached.

Suggested Prefixes for Variables and Function Names


Finally, we discuss prefixes for variables and function names; these suggestions are derived from both VB Books Online and MSDN.

Data type Boolean

Prefixes bln or b

Example blnFound or bFound

Appendices 191

Byte Collection object Currency Date (Time) Double Error Integer Long Object Single String User-defined type Variant

byt col cur or c dtm or dt dbl or d err int or i or n lng or l obj sng str or s udt vnt or v

bytRasterData colWidgets curRevenue or cRevenue dtmStart or dtStart dblTolerance or dTolerance errOrderNum intQuantity or iQuantity or nQuantity lngDistance or lDistance objCurrent sngAverage strFName or sFName udtEmployee vntCheckSum or vCheckSum

192 Fundamentals of GeoMedia Development Part I

PowerBuilder Syntactical Differences


Since most of the examples in the course materials and exercises use Visual Basic syntax, the following table shows some equivalent operations in PowerBuilder syntax.

Visual Basic

PowerBuilder

To declare an automation object: Dim objLegend As New Legend -orDim objLegend As Legend Set objLegend = CreateObject (GeoMedia.Legend) OLEObject objLegend objLegend = Create OLEObject objLegend.ConnectToNewObject (GeoMedia.Legend)

To release an object: Set objLegend = Nothing objLegend.DisconnectObject Destroy objLegend

PowerBuilder has no default properties, so you must explicitly reference every property or method, as in the case of the Item method on a collection. You index an array or collection with [ ] in PowerBuilder as opposed to ( ) in Visual Basic. Application.Windows(2) Application.Windows.Item[2]

When using custom controls in PowerBuilder, you need to use the keyword Object as the member property of the control before referencing any of the controls properties or methods. ocxMapView.Legend ocxMapView.Object.Legend

PowerBuilders definition of True and False is not exactly the same as Visual Basics, so it is safest to use 1 and 0 for True and False,

Appendices 193

respectively. objLegend.Visible = True objLegend.Visible = False objLegend.Visible = 1 objLegend.Visible = 0

Additionally, in PowerBuilder, as in Visual Basic, the dot is the navigational operator for accessing an objects properties and methods. There is no For Each in PowerBuilder; you must use a For loop with a counter or index. There is no TypeName() or Type Of in PowerBuilder; you must write a VB automation server that you call from PowerBuilder if you need to determine the type of an object. You can pass the object and VB can still determine its type. There is no equivalent concept to a With block in PowerBuilder, so it is important to create temporary variables to store deep-nested objects. In PowerBuilder, you need to use the Ref keyword on return arguments from methods.

194 Fundamentals of GeoMedia Development Part I

Delphi and GeoMedia


Refer to the technical note, Developing GeoMedia Applications with Delphi, on the Team GeoMedia web site for hints and tips on using GeoMedia with Delphi.

Appendices 195

Automation Overview Diagrams


In addition to the standard product documentation, we have prepared a quick reference guide to the automation model for GeoMedia. You can find this file on the floppy labeled Fundamentals of GeoMedia Development Part I Workshop Materials. The file, GeoMediaAuto.hlp, is a standard Windows help file. Double click on the file to start help. By clicking on the hot spots within the graphics, you will get a summary of the objects properties and methods. The file has been copied to c:\TGM\GeoMediaAuto.hlp for access during the workshop.

196 Fundamentals of GeoMedia Development Part I

OriginatingPipe GRecordset vs. GDO GRecordset


Most communication of data in GeoMedia is done through the use of a GRecordset object. GRecordset objects can be created in two ways. The primary mechanism is through the GDO OpenRecordset method on the GDatabase object. The alternative method is through the use of a pipe. A pipe is a software component that accepts input data in the form of a GRecordset and outputs data in the form of a GRecordset. The interface to the object (its method and properties) is exactly the same whether created by GDO or through a pipe. Then why are there two mechanisms? Pipe-based recordsets add value to the system. Specifically, they provide Persistence Notification Metadata access Recordset naming Error access CoordSystem access

These additions add significant power to GeoMedia. Except for persistence, all of these additions are available in custom applications. To ensure full access to all of these capabilities, you should use OriginatingPipe to create all of your recordsets. OriginatingPipe is a special pipe which creates a GRecordset just as you would with GDO. In fact, it internally creates a recordset with GDatabase.OpenRecordset.

Appendices 197

Programming Caveats
GeoMedia does not exit cleanly
It is probable that you will encounter situations in which GeoMedia does not exit cleanly after running your commands. The executable (GeoMedia.exe) will remain in memory until all references on its automation objects are reduced to zero. If you are encountering this situation, your command is probably holding a global variable referencing one of these objects: GeoMedia.Application, GeoMedia.Document, GeoMedia.MapViewWindow, GeoMedia.DataViewWindow, and any other object found under the application object in the automation diagram. To correct the situation, you must set the global objects to Nothing. In general, this should be done as soon as you have completed all operations using that object. In all situations, this must be done by the time the execution of your commands terminate method is completed.

When is it safe to keep an object reference?


In general, you should reduce or eliminate global variables in your commands. Obviously, this is not always possible. However, certain situations dictate that you release the objects referenced by your global variables to avoid intermittent crashes. The only two GeoMedia objects which can safely be referenced between command initiations are the application object and the map view listeners object. These objects were passed to the command in the Initialize method and are guaranteed to be valid until the command is terminated. Although in theory, an object will not be destroyed until all references are zero, the GeoMedia development staff has diagnosed conditions in which MFC will ignore the reference counts and destroy the object prematurely. If you then try to reference such an object, your command will cause GeoMedia to crash. In general, you should not retain references to any objects under the document object in the automation hierarchy between initiations of the command.

CreateObject versus CreateService


You will find a method on the application object, CreateService, which acts like the built-in CreateObject function. In fact, CreateService does perform the same function as CreateObject - it creates an instance of the object specified by the ProgID sent as the methods parameter. Why would you use one method over the other? The only reason to use Application.CreateService is to sidestep some problems in marshaling of

198 Fundamentals of GeoMedia Development Part I

data between process boundaries. When will you cross process boundaries? Any time you have two executables running on your system and you are communicating between them, the data is crossing process boundaries. When GeoMedia is one of the processes, you should use Application.CreateService to create any GeoMedia objects that will be saved in the GeoMedia workspace. By using this method, GeoMedia creates the object, and the memory is allocated in GeoMedias process space. This allows GeoMedia to correctly persist its data. NOTE: Marshaling is the packaging and sending of interface method calls across thread or process boundaries. Essentially, marshaling is the technique used to translate data addresses from one process space to another.

A query in the collection might be invalid or closed


When accessing recordsets within GeoMedia through the QueryFolder.Queries collections, you may encounter recordsets that are invalid or closed. An invalid recordset is caused by a change to the schema that prevents the server from providing the requested data. For example, you may have a query for all Roads where NumLanes >2. If the schema or metadata for Roads has changed such that the attribute NumLanes no longer exists, the recordset is invalid.

To ensure a recordset is open before you access it, the following code should be used: Dim objNotify as Object Set objNotify = Nothing On Error Resume Next Set objNotify = objRecordset.GetExtension(Notification) On Error GoTo AccessFailed If objNotify Is Nothing Then assume that the recordset is open and continue Else objNotify.Reopen End If There is no cost to reopen the recordset if it is already open.

Appendices 199

Feature Selection Controls


The feature selection controls, GMFeatureListBox and GMFeatureComboBox, are custom controls (OCXs) that present the connection, feature, and query information in a tree view. If you are creating GeoMedia commands, you may use these controls. This section provides the documentation necessary to utilize the controls. Both controls operate in a similar fashion. They are not available in custom applications as they require a GeoMedia document as an initialization value.

Property/Method ClearSelectedItem ConnectionName

Data Type Boolean String

Description Clears any selected item in the tree. Name of connection selected in the tree. Not applicable if a query is selected. Indicates whether or not connections should be displayed in the tree. Pointer to the geoworkspace document. Must be set before the control is displayed. Must be released before the command exits. Flag to indicate if the table names should be shown as Connection.Table. Only applicable to GMFeatureCombobox. Mask of MetadataTableConstants that controls the list of tables by inclusion of the specified primary geometry types. Not applicable to queries displayed in the tree. To display all tables, specify zero (0) for the mask. Flag to indicate if query objects should be included in the tree.

ConnectionsVisible

Boolean

Document

Document

FullName

Boolean

GeometryTypesVisible

Long

QueriesVisible

Boolean

200 Fundamentals of GeoMedia Development Part I

ReadonlyVisible

Boolean

Flag to indicate if read only connections should be included in the tree. Method to force the tree to update after you have changed properties. Value of the selected leaf node. One of three constant values indicating the nature of the users selection in the tree: gmfcNoSelection, gmfcConnection, or gmfcQuery. Method you must call after you have specified the ConnectionName, SelectedItem, and SelectedType so that the default tree entry can be highlighted.

Refresh

Void

SelectedItem SelectedType

String Integer

ValidateSelectedItem

Boolean

All other properties have the same definition as other controls.

Appendices 201

Raster Formats
General Information
GeoMedia will support any raster image that has been georeferenced with Intergraph software using the transformation matrix. In GeoMedia, this type of file is placed using the "By Header" option and the user must specify a design file so that GeoMedia can determine the correct working units to apply to the transformation matrix. GeoMedia will support any raster image that has been georeferenced with the geo_tie_pkt application packet. In GeoMedia, this type of file is placed using the "Georeferenced" option. This is an Intergraph format. GeoMedia will support most common non-georeferenced raster formats. In GeoMedia, this type of file is placed using the "Interactive" placement option.

Supported Formats
Intergraph (*.cot *.cit *.crl *.rgb *.rle *.tg4) Bitmap (*.bmp) TIFF (*.tif) In V1.0, placement by header was not supported. It is available in V2.0 for industry standard geo_tif_pkt for placement by header.

GIF (*.gif) IGS (*.rlc *.igs) JPeg (*.jpg) Hitachi (*.hrf) PCX (*.pcx) CALS (*.cal)

202 Fundamentals of GeoMedia Development Part I

GetExtension Method
The GDO specification includes a mechanism on the GDatabase, GRecordset, and GField objects to expose additional capabilities associated with a server. Additionally, GeoMedia provides a series of client side extensions. These extensions typically provide additional capabilities associated with object. The syntax for retrieving the extension object is:
dim objExt as Object set objExt = myObject.GetExtension(ExtensionName)

where myObject is a reference to one of the GDO objects. ExtensionName is replaced by one of the names specified in the following tables. You may strongly type the extension object.

GDatabase Extensions
The following extensions may be retrieved. Extension Name FRMAdminExtension Object Type Returned GFRMAdminExtension **

**This extension is only applicable to the GDO FRAMME server.

GRecordset Extensions
The following extensions may be retrieved. Extension Name Name Notification ExtendedPropertySet OriginatingPipe SpatialQueryPipe AttributeFilterPipe CSSTransformPipe SortPipe Errors Object Type Returned Query Notification ExtendedPropertySet OriginatingPipe SpatialQueryPipe AttributeFilterPipe CSSTransformPipe SortPipe GErrors

Appendices 203

CenterPointPipe EquijoinPipe GraphicsTextPipe MovePipe SchemaProjectPipe SpatialFilterPipe

CenterPointPipe EquijoinPipe GraphicsTextPipe MovePipe SchemaProjectPipe SpatialFilterPipe

GField Extensions
The following extensions may be retrieved. Extension Name ExtendedPropertySet CoordSystem Errors Object Type Returned ExtendedPropertySet GRecordset GErrors

204 Fundamentals of GeoMedia Development Part I

ExtendedPropertySet.GetValue Method
The ExtendedPropertySet provides access to the client side metadata information about the recordsets underlying table and fields. The method, GetValue, returns the value of the property specified by the input argument. The input argument corresponds to the names of the fields in the metadata tables. The available values are specified below. The syntax for retrieving the value is: dim strValue as Variant strValue = objExtendedPropertySet.GetValue(Property) where objExtendedPropertySet is a reference an ExtendedPropertySet object retrieved through GetExtension from either the GRecordset or the GField objects. Property is replaced by one of the names specified in the following tables.

GRecordset
Property Name Name Returned Value String containing the name of the table upon which the recordset is defined. This may be empty if the recordset is not based directly on a warehouse table. Long integer containing the subtype of the geometry field specified by the next property. The values correspond to the GDO geometry types. A special case situation exists where this value is gdbGraphic. This indicates that there are no spatial geometries within the recordset. String containing the name of the geometry field that contains the primary or default gdbSpatial field. This string will be empty if the recordset contains no spatial fields. String containing a user description of the underlying table.

GeometryType

PrimaryGeometryFieldName

Description

Appendices 205

GField
Property Name Key Returned Value Boolean value indicating if this field is the primary unique key for the recordset. Only applicable to non-geometry fields. String containing information about the technique to use to format the value of the field. Refer to the Technical Paper: Metadata Layout for information on the format values. Only applicable to non-geometry fields. Short integer containing the type of the field. The value is one of the GDO data types. Only applicable to non-geometry fields. Boolean value indicating whether or not the field should be displayed in the Data View or Object Properties dialogs. Only applicable to non-geometry fields. Short integer indicating the number of decimal places to display for numeric data. Only applicable to non-geometry fields. String containing a user description of the underlying table. Boolean value indicating whether or not this gdbSpatial field is the primary or default field. Only applicable to geometry fields. Long integer corresponding to the SubType of the field. The values corresponds to GDO geometry types. Only applicable to geometry fields. String value containing the GCoordSystemGUID associated with the field. Only applicable to geometry fields. Gets or set the name (string) of the table containing the geometry field to be indexed. Need only be specified on a table created within a database session. Set operation is only applicable to the GField object of a GTableDef object. This is extension is currently supported

Format

Type

Displayable

Precision

Description PrimaryGeometryFlag

GeometryType

GCoordSystemGUID

SpatialKeyTableName

206 Fundamentals of GeoMedia Development Part I

by the Access server. SpatialKeyFieldName Gets or sets the name (string) of the spatial key field. The set operation is only applicable to a GField object on a GTableDef object. This is extension is currently supported by the Access server.

Appendices 207

Common Interfaces
IUnknown
All COM objects will implement this interface. The methods within the interface are: AddRef - adds a references to the object Release - releases a reference on the object QueryInterface - allows the client to ask if the object supports the specified interface

IDispatch
All automated objects will implement this interface. The methods within the interface are: Invoke - provides access to the properties and methods exposed on an object GetIDsOfNames - retrieves the interface IDs for the named member GetTypeInfo - retrieves the type information for an object GetTypeInfoCount - retrieves the number of type information interfaces that an object provides (either 0 or 1).

208 Fundamentals of GeoMedia Development Part I

Type Libraries and Objects


GeoMedia delivers a number of files containing information about the objects and their methods and properties. These files can be categorized into three groups: OLE controls, GDO, and GeoMedia.

Category OLE Controls

Type Library dataview.tlb defcoordsystem.tlb mapview.tlb ntharrw.tlb ScaleBar.tlb gmevent1.ocx (type library not separate from control) gmfeaturecontrols.tlb Pcontrol.ocx (type library not separate from controls)

GDO

ExtendedPS.tlb GDO.tlb GDOFRM.tlb CADIGDSScanner.tlb CADODBCScanner.tlb GCADServer.tlb

GeoMedia

GeoMedia.tlb PAdvLgd.tlb Pbasic.tlb PClCmd.tlb Pclient.tlb PCmdMgr.tlb PCSS.tlb PDBPipe.tlb PGeoMath.tlb

Appendices 209

Ppipe.tlb Praster.tlb PService.dll/tlb Pview.tlb

210 Fundamentals of GeoMedia Development Part I

The objects and their corresponding type libraries are listed here alphabetically by object name.

Object *Font Accelerator Accelerators AltCoordSystemPath AltCoordSystemPaths AnyStyle Application AreaStyle ArcGeometry AttributeFilterPipe AutoPanService BitmapStyle BoundaryGeometry BufferZonePipe BursaWolf Categories Category CenterPointPipe ColorScheme ColorSchemes Command Commands ComplexPolynomial

Type Library Standard OLE Types GeoMedia GeoMedia PCSS PCSS PView GeoMedia PView Pbasic PDBPipe PService PView Pbasic PPipe PCSS GeoMedia GeoMedia PPipe PView PView GeoMedia GeoMedia PCSS

ProgID Prefix

GeoMedia Framework

Not Creatable Not Creatable Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GMService GeoMedia GeoMedia GeoMedia Not Creatable Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia Not Creatable Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia GeoMedia

X X

X X

X X

CompositePolygonGeometry Pbasic CompositePolylineGeometry Pbasic Connection Connections CoordSystem CoordSystemsMgr PClient PClient PCSS PCSS

Appendices 211

CSSTransformPipe DataWindow DatumTransformation DisplayedObjects DockableControl DockableControls DocSelectedObjects Document EllipsoidStrings EquijoinPipe EventServer ExtendedPropertySet FieldProperty GDatabase

PDBPipe GeoMedia PCSS PView GeoMedia GeoMedia PClient GeoMedia PCSS PDBPipe PBasic PClient PService GDO

GeoMedia Not Creatable X

GeoMedia Not Creatable Not Creatable GeoMedia GeoMedia Not Creatable GeoMedia GeoMedia Not Creatable GMService
Access, AI, GW MGE, FRAMME, MGSM, AV, MGDM, GCAD

X X X X

GeodeticDatumStrings GeogSpace GeometryCollection GeometryDigitizeService GeometryEditService GeometryObject GeometryStorageService GError GErrors GField GFields GFRMAdminExtension GFRMSeg GFRMSegs GIndex GIndexes GMDataView GMDefCoordSystem

PCSS PCSS PBasic PClient PClient PView PClient GDO GDO GDO GDO GDOFRM GDOFRM GDOFRM GDO GDO DataViewLib DefCoordSystemLib

Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia Not Creatable Not Creatable Not Creatable Not Creatable Not Creatable Not Creatable Not Creatable Not Creatable Not Creatable Control GeoMedia

212 Fundamentals of GeoMedia Development Part I

GMEventControl GMFeatureCombobox GMFeatureListbox GMMapView GMNorthArrow GMScaleBar GMViewListeners GraphicsTextPipe GRecordset GRecordsets GTableDef GTableDefs HandleStyle LeastSquares Legend LegendEntries Legends LinearModelResidual LinearStyle LineGeometry Link Links LocatedObjectsCollection MapWindow Matrix MeasurementService MenuBar MenuBars MenuItem MenuItems MetadataService MovePipe MultipleRegression

GMEventControLib GMFeatureControlsLib GMFeatureControlsLib MapViewLib GMNorthArrow ScaleBarLib PCmdMgr PService GDO GDO GDO GDO PView PCSS PView PView PView PCSS PView PBasic PCSS PCSS PView GeoMedia Pbasic PClient GeoMedia GeoMedia GeoMedia GeoMedia PService PPipe PCSS

Control Control Control Control Control Control Not Creatable GMService Not Creatable Not Creatable Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia Not Creatable GeoMedia GeoMedia Not Creatable Not Creatable GeoMedia Not Creatable GeoMedia GeoMedia Not Creatable Not Creatable Not Creatable Not Creatable GMService GeoMedia Not Creatable X X X X X X

Appendices 213

NonlinearModelResidual Notification Observation Observations OrientedPointGeometry OriginatingPipe OutputTableService PaperSpace PatternedAreaStyle PatternedLinearStyle PickQuickDialog Point PointGeometry Points PointSymbolStyle PolygonGeometry PolylineGeometry PreferenceSet ProjAlgorithmStrings ProjSpace Queries Query QueryFolder QueryFolders Range RangeLegendEntry Ranges RasterGeometry RasterLegendEntry RasterObject RasterPropertiesService RecordLegendEntry RecordObject

PCSS PClient PCSS PCSS PBasic PClient PService PCSS PView PView PService PBasic PBasic PBasic PView PBasic PBasic PService PCSS PCSS PDBPipe PDBPipe PDBPipe PDBPipe PAdvLgd PAdvLgd PAdvLgd PRaster PRaster PRaster PRaster PView PView

Not Creatable Not Creatable Not Creatable Not Creatable GeoMedia Not Creatable GMService Not Creatable GeoMedia GeoMedia GMService GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GMService Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia Not Creatable GeoMedia GeoMedia GeoMedia

214 Fundamentals of GeoMedia Development Part I

RecordsetObject RectangleGeometry RefSpaceMgr SchemaProjectPipe SecondDegreePolynomial ServerTransService SingleParameterConstraint SingleParameterConstraints SmartLocateService SnapService SortKey SortKeys SortPipe SpatialFilter SpatialFilterPipe SpatialFilters SpatialQueryPipe StandardMolodensky StatisticsService Symbol SymbolFileService SymbolFontStyle SymbolNames TableProperty TextPointGeometry TextStyle ToolBar ToolBarButton ToolBarButtons ToolBars TransLinks UniqueValue UniqueValueLegendEntry

PView PBasic PCSS PDBPipe PCSS PClient PCSS PCSS PBasic PClient PPipe PPipe PPipe PClient PDBPipe PClient PPipe PCSS PClCmd PView PView PView PView PService PBasic PView GeoMedia GeoMedia GeoMedia GeoMedia PCSS PAdvLgd PAdvLgd

GeoMedia GeoMedia Not Creatable GeoMedia Not Creatable GeoMedia Not Creatable Not Creatable GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia GeoMedia Not Creatable GeoMedia Not Creatable GeoMedia GeoMedia Not Creatable GMService GeoMedia GeoMedia Not Creatable Not Creatable Not Creatable Not Creatable Not Creatable GeoMedia GeoMedia X X X X

Appendices 215

UniqueValues UnitFormatSpec UnitIDs UnitsOfMeasure Vector Windows

PAdvLgd PCSS PCSS PCSS Pbasic GeoMedia

GeoMedia Not Creatable Not Creatable

GeoMedia Not Creatable X

216 Fundamentals of GeoMedia Development Part I

Object Bundles
In addition to the standard product offerings, Intergraph will accommodate the sale of object bundles. That is, you can use a subset of the GeoMedia objects without installing GeoMedia on each users machine. Object bundle sales must be negotiated as an OEM (Original Equipment Manufacturer) agreement with Intergraph. Please contact the Team GeoMedia Technical Staff at techtgm@ingr.com for more information on the requirements of this program and associated pricing. The basic object bundles are categorized here.

Object Set Name MapView

Description Map view display complete with smart legend, object locate, north arrow, scale bar, and geometry objects. Record legend entry is included which provides for the display of vector data, including the supported styles. Requires at least one data server. Extends the map view object set with raster display. Extends the map view object set with thematic map displays for both unique value and range thematics. Extends the map view object set with the ability to generate, display and store buffer zones. Requires the Access Data Server. Extends the map view object set with the ability to perform spatial analysis against one or more data sources. Extends the map view object set with the ability to perform dynamics in the generation of new features. Requires the Access Data Server. Provides the ability to read and write GIS data in an Access compatible data base. Microsoft Access is not required. Provides read-only access to MGE databases. An ODBC driver for the relational database used by

Raster Thematics

Buffer Zone

Adv. Analysis

Edit/Redline

Access Data Server

MGE Data Server

Appendices 217

the MGE database is required.

FRAMME Data Server Provides read-only access to a FRAMME database. MGSM Data Server Oracle Data Server (RO) ArcInfo Data Server Provides read-only access to a MGSM database. Provides read-only access to an Oracle database with or without SDO. The ability to import data into Oracle is NOT supported by this object. Provides read-only access to ArcInfo coverages.

** As a minimum, you must purchase the MapView set of objects.

218 Fundamentals of GeoMedia Development Part I

The following chart indicates the composition of the above described object sets, including objects and type libraries.

OBJECT

TYPE LIBRARY

OBJECT SET NAME MAPVIEW

AltCoordSystemPath AltCoordSystemPaths AnyStyle AreaStyle BitmapStyle BoundaryGeometry ColorScheme ColorSchemes CoordSystem CoordSystemsMgr DisplayedObjects EllipsoidStrings EventServer GeodeticDatumStrings GeogSpace GeometryCollection GeometryObject GeometryStorageService GMDefCoordSystem GMEventControl GMMapView GMNorthArrow GMScaleBar HandleStyle Legend LegendEntries Legends Linear Style

PCSS PCSS PView PView PView PBasic PView PView PCSS PCSS PView PCSS PBasic PCSS PCSS PBasic PView PClient DefCoordSystemlib GMEventControllib MapViewLib GMNorthArrow ScaleBarLib PView PView PView PView PView

MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView

Appendices 219

LineGeometry Link Links LocatedObjectsCollection MeasurementService OrientedPointGeometry PageSetup PaperSpace Point PointGeometry Points PolygonGeometry PolylineGeometry PreferenceSet Print ProjAlgorithmStrings ProjSpace RecordLegendEntry RecordObject RecordsetObject RectangleGeometry RefSpaceMgr SmartLocateService SymbolFontSytle TextPointGeometry TextStyle TransLinks UnitFormatSpec UnitIDs UnitsOfMeasure

PBasic PCSS PCSS PView PClient PBasic PClCmd PCSS PBasic PBasic PBasic PBasic PBasic PService PClCmd PCSS PCSS PView PView PView PBasic PCSS PBasic PView PBasic PView PCSS PCSS PCSS PCSS

MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView MapView RASTER

RasterGeometry RasterLegendEntry

PRaster PRaster

Raster Raster

220 Fundamentals of GeoMedia Development Part I

RasterObject RasterPropertiesService

PRaster PRaster

Raster Raster THEMATICS

Field Property Range RangeLegendEntry Ranges SortKey SortKeys SortPipe StatisticsService TableProperty UniqueValue UniqueValueLegendEntry UniqueValues

PService PAdvLgd PAdvLgd PAdvLgd PPipe PPipe PPipe PClCmd PService PAdvLgd PAdvLgd PAdvLgd

Thematics Thematics Thematics Thematics Thematics Thematics Thematics Thematics Thematics Thematics Thematics Thematics BUFFERZONE

BufferZonePipe

PClCmd

BufferZone ADVANCED ANALYSIS

AttributeFilterPipe Connection Connections CSSTransformPipe GMDataView GMFeatureCombobox GMFeatureListBox MetadataService Notification OriginatingPipe Queries Query QueryFolder QueryFolders ServerTransService

PPipe PClient PClient PClient DataView GMFeatureControlsLib GMFeatureControlsLib PService PClient PClient PClient PClient PClient PClient PClient

Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysi Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis Advanced Analysis

Appendices 221

SpatialQueryPipe

PPipe

Advanced Analysis EDIT/REDLINE

GeometryDigitizeService GeometryEditService

PClient PClient

Edit/Redline Edit/Redline

222 Fundamentals of GeoMedia Development Part I

Collections: Indexing and Object Types


This section describes the available collections within GeoMedia. It identifies the indexing technique (zero or one relative) and the type of objects contained in each collection.

Collection

Object

Heterogeneous

Index Relative To 1 1 1 1 1 1

Accelerators AltCoordSystemPaths Categories ColorSchemes Commands CompositePolygonGeometry

Accelerator AltCoordSystemPath Category ColorScheme Command LineGeometry, PolylineGeometry, ArcGeometry, CompositePolylineGeometry LineGeometry, PolylineGeometry, ArcGeometry, CompositePolylineGeometry Connection See HighlightedObjects & MapViewSelectedObjects DockableControl GeometryCollection, CompositePolylineGeometry, CompositePolygonGeometry, ArcGeometry, PointGeometry, OrientedPointGeometry, TextPointGeometry, LineGeometry, PolylineGeometry, RectangleGeometery, PolygonGeometry, BoundaryGeometry, RasterGeometry Gerror GField GFRMSeg Gindex GRecordset GTableDef

No No No No No Yes

CompositePolylineGeometry

Yes

Connections DisplayedObjects DockableControls GeometryCollection

No Yes No Yes

1 1 1 1

GErrors GFields GFRMSegs Gindexes Grecordsets GTableDefs

No No No No No No

0 0 0 0 0 0

Appendices 223

HighlightedObjects Holes LegendEntries

GeometryObject, RecordObject, RecordsetObject, RasterObject RectangleGeometery, PolygonGeometry RecordLegendEntry, RasterLegendEntry, RangeLegendEntry, UniqueValueLegendEntry Legend Link GeometryObject, RecordsetObject, RasterObject GeometryObject, RecordObject, RecordsetObject, RasterObject MenuBar MenuItem Observation Point Query QueryFolder Range GeometryObject, RecordObject, RecordsetObject, RasterObject SortKey SpatialFilter ToolBarButton ToolBar TransLink UniqueValue DataWindow, MapWindow

Yes Yes Yes

1 1 1

Legends Links LocatedObjectsCollection MapViewSelectedObjects MenuBars MenuItems Observations Points Queries QueryFolders Ranges SelectedObjects SortKeys SpatialFilters ToolBarButtons ToolBars TransLinks UniqueValues Windows

No No Yes Yes No No No No No No No Yes No No No No No No Yes

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

224 Fundamentals of GeoMedia Development Part I

Object Types in Heterogeneous Collections


CompositePolygonGeometry, CompositePolylineGeometry
Contains a mixture of LineGeometry, PolylineGeometry, ArcGeometry, and CompositePolylineGeometry objects. This collection is heterogeneous and indexed relative to 1.
Object CompositePolylineGeometry Value Returned by TypeName DGMCompositePolylineGeometry Value of Type Property CompositePolyline Geometry LineGeometry PolylineGeometry ArcGeometry DGMLineGeometry DGMPolylineGeometry DGMArcGeometry LineGeometry PolylineGeometry ArcGeometry

GeometryCollection
Contains a mixture of GeometryCollection, PointGeometry, OrientedPointGeometry, TextPointGeometry, LineGeometry, PolylineGeometry, RectangleGeometery, PolygonGeometry, BoundaryGeometry, and RasterGeometry objects. This collection is heterogeneous and indexed relative to 1.
Object ArcGeometry CompositePolygonGeometry Value Returned by TypeName DGMArcGeometry DGMCompositePolygon Geometry CompositePolylineGeometry DGMCompositePolyline Geometry GeometryCollection PointGeometry OrientedPointGeometry TextPointGeometry LineGeometry DGMGeometryCollection DGMPointGeometry DGMOrientedPointGeometry DGMTextPointGeometry DGMLineGeometry Value of Type Property ArcGeometry CompositePolygon Geometry CompositePolyline Geometry GeometryCollection PointGeometry OrientedPointGeometry TextPointGeometry LineGeometry

Appendices 225

PolylineGeometry RectangleGeometery PolygonGeometry BoundaryGeometry RasterGeometry

DGMPolylineGeometry DGMRectangleGeometry DGMPolygonGeometry DGMBoundaryGeometry DGMRasterGeometry

PolylineGeometry RectangleGeometry PolygonGeometry BoundaryGeometry RasterGeometry

DisplayedObjects, HighlightedObjects, MapViewSelectedObjects


Contains a mixture of GeometryObject, RecordObject, RecordsetObject, and RasterObject objects. This collection is heterogeneous and indexed relative to 1.
Object GeometryObject RecordObject RecordsetObject RasterObject Value Returned by TypeName GeometryObject RecordObject RecordsetObject DGMRasterObject Value of Type Property GeometryObject RecordObject RecordsetObject RasterObject**

Holes
Contains a mixture of RectangleGeometry and PolygonGeometry objects. This collection is heterogeneous and indexed relative to 1.
Object RectangleGeometery PolygonGeometry CompositePolygonGeometry Value Returned by TypeName DGMRectangleGeometry DGMPolygonGeometry DGMCompositePolygonGeometry Value of Type Property RectangleGeometry PolygonGeometry CompositePolygon Geometry

226 Fundamentals of GeoMedia Development Part I

LegendEntries
Contains a mixture of RecordLegendEntry, RasterLegendEntry, UniqueValueLegendEntry, and RangeLegendEntry objects. This collection is heterogeneous and indexed relative to 1.
Object RecordLegendEntry RasterLegendEntry RangeLegendEntry UniqueValueLegendEntry Value Returned by TypeName DGMRecordLegendEntry DGMRasterLegendEntry DGMRangeLegendEntry DGMUniqueValueLegendEntry Value of Type Property RecordLegendEntry RasterLegendEntry RangeLegendEntry UniqueValueLegend Entry

LocatedObjectsCollection
Contains a mixture of GeometryObject, RecordsetObject, and RasterObject objects. This collection is heterogeneous and indexed relative to 1.
Object GeometryObject RecordsetObject RasterObject Value Returned by TypeName GeometryObject RecordsetObject DGMRasterObject Value of Type Property GeometryObject RecordsetObject RasterObject**

SelectedObjects
Contains a mixture of GeometryObject, RecordObject, RecordsetObject, and RasterObject objects. This collection is heterogeneous and indexed relative to 1.
Object GeometryObject RasterObject RecordObject Value Returned by TypeName GeometryObject DGMRasterObject RecordObject Value of Type Property GeometryObject RasterObject** RecordObject

Appendices 227

RecordsetObject

RecordsetObject

RecordsetObject

Windows
Contains a mixture of DataWindow and MapWindow objects. This collection is heterogeneous and indexed relative to 1.
Object DataWindow MapWindow Value Returned by TypeName Object Object Value of Type Property DataWindow MapWindow

** The Type property of a RasterObject currently returns a blank string. A software trouble report (TR) has been logged.

228 Fundamentals of GeoMedia Development Part I

Appendices 229

Instructors Overheads
The following pages provide you with copies of the overheads used during the workshop sessions.