Wednesday, June 29, 2005
I will present both VB and VC++ code for launching GTViewer, but I will be more detailed on the VB code since I believe that there are more people using VB with GTViewer than VC++.
The first thing you should do in VB after you create a new project, is select Project/References and browse for the GTViewer.tlb file. This file is delivered with GTViewer and it tells VB how to communicate with GTViewer. After selecting this reference, the intellisense will work in VB for GTViewer types and its methods will show parameters and return types.
Next, you should define three variables in the declaration section. You may or may not use all three, but it is good to have them available:
Dim app As GTViewer.Application
Dim view As GTViewer.view
Dim doc As GTViewer.Document
To launch GTViewer, you use the CreateObject function like the following:
Set app = CreateObject("GTViewer.application")
If GTViewer is already running, it will attach to the running one (only one instance of GTViewer is ever allowed to run for this very reason).
The next step is to turn on the display of GTViewer. The default is to be hidden, so you must explicitly show the application:
This is all you need to do to get GTViewer running. Now let’s open a file:
The file can be a .gtm, a .gtx, a .gtw, or a .gts.
The next part is a little tricky. We want to perform some operation on the view, but it takes some time for GTViewer to get the view open and available. One of the Application methods is GetActiveView. We will call this method to get a pointer to the active view that was just created by the OpenFile method; however, we must check to see if it is valid before we try to use it and then try to get it again if it is not.
Set view = app.GetActiveView
Dim count As Integer
count = 10 ' maximum of 10 tried
While view Is Nothing And count > 0
Sleep 250 ' pause a quarter of a second
Set view = app.GetActiveView
count = count - 1
There are many ways to get a valid view handle, but this seems like the simplest and most straightforward.
Now that we have access to a view, what do we do? I am going to set the view on a particular point that we provide. This job is easy to do with the SetViewCenter method which can location on both system coordinates (internal to GTViewer) or computed coordinates (used by the original data). However, to make this code segment even more usable, I am going to say that our coordinate is a Latitude/Longitude pair. So, we must convert the lat/long values to appropriate values for our data. This is easy to do as well, but there are a few requirements. The FromLatLong method we are going to use depends on the GPS Component being installed and the Coordinate System properly specified in the data (which may or not be done). The FromLatLong method is also part of the Document methods, so we must get a document object to work with:
Set doc = app.GetActiveDocument
Next, if our doc object and view object are valid, we convert the point and call SetViewCenter:
If Not doc Is Nothing And Not view Is Nothing Then
Dim latitude As Double
Dim longitude As Double
Dim x As Double
Dim y As Double
latitude = 34.653138583526
longitude = -86.4846563804903
If doc.FromLatLong(latitude, longitude, 1, x, y) Then
view.SetViewCenter 1, x, y, 1000
I have just hardcoded a lat/long value into the code so that it will have something to locate on.
That’s it! You can use any of the methods GTViewer provides. These methods are documented in GTVx.doc.
For the VC++ programmer, I will quickly run through some of the major steps. You will create a new class using the GTViewer.tlb file as the first step. This class is a wrapper for the GTViewer methods and is used like the following:
double lat =34.653138583526;
double lon = -86.4846563804903;
double zoom = 1000.0;
m_gtviewer=new IAutoMain; // Create an instance of GTViewer
sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)",
m_gtviewer->Show(1); // must show the GTViewer app
m_gtviewer->OpenFile(m_file); // Open specified file
while (v==NULL && count>0) // try until a valid dispatch
Sleep(250); // sleep a quarter of a second
v = m_gtviewer->GetActiveView(); // Get Dispatch for active view
d = m_gtviewer->GetActiveDocument(); // Get Dispatch for active doc
if (v && d) // if a view dispatch was retrieved
view.AttachDispatch(v); // attach dispatches
long mode=1; // mode 1 = computed coordinates
double x, y;
doc.FromLatLong( lat, lon, mode, &x, &y );
view.SetViewCenter(mode, x, y, zoom);
Tuesday, June 28, 2005
The sample Lightning Strike data was comma separated data. I renamed the file (to lightning.csv from lightning.txt) and I also placed column headers as the first row. The column headers are not necessary, but FME will use them if they are there:
Time, X, Y
6/27/2005 12:42:27 PM, 457382500, 1515628500
6/27/2005 12:42:30 PM, 456551000, 1515066000
6/27/2005 12:42:47 PM, 457590400, 1514540200
In FME Workbench, I created a new workspace and selected a CSV file as the source and GTI_GTViewer as the destination:
This new workspace looks like the following:
Since the .CSV file is just tabular data, we have to add a few FME transformers to create the geometry like we want it. I want the resulting .gtg file to be equivalent to the one produced by GTCreate in the previous post, so this task is slightly more complicated that just doing a default conversion with a single 2DPointAdder transformer.
I am going to add three transformers: a Counter, a Concatenator, and a 2DPointAdder. The data in the .CSV file did not have any kind of ID, so I am using a Counter to just add a new value that gets incremented for each feature (the GTCreate example had a counter too that was incremented for each line read out of the file). The 2DPointAdder takes the X and Y values from the .CSV file and generates a point geometry. I am going to differ from the GTCreate version here by placing a point feature (Symbol) rather than a Circle, but this is a trivial change if you wanted to do it with a circle. Finally, I am going to use a Concatenator to generate the string of data to embed on the new elements. This embedded data string is the same string used with GTCreate that includes the Id and Time of the strike. A big difference can be seen here between the GTCreate and the FME approaches. FME will automatically create an ASCII Data set (data.txt, data.idx, and data.tab) and link the elements to the rows in the data file. However, I used embedded data in the GTCreate version so that the file would be a single self-contained file that still supports reviewable features. If you were going to add this data as a new Category in GTViewer, leaving the data separate and using the linkages is a better approach (See the Linkages and Embedded Data posting for more info on this).
The end result is the following workspace:
Run the Translation and you will get a complete GTViewer dataset that includes a Lightning.gtg file equivalent to the one produced by the GTCreate example.
Probably the only complicated part of this workspace is creating the embedded data. The GTViewer Writer for FME is geared for creating linked data (since this is what you typically do); nevertheless, it is still very easy to embed data on elements. The Concatenator just builds the string using the ID and Time data values and then on the Destination dataset, the gti_embeddedData is set to the result of the concatenation and gti_embeddedDataType is set to 1 (a constant value).
The FME approach is very different from the GTCreate approach, but the end result is the same. The approach you take will probably depend on which tools you have and what you are more comfortable doing. The GTCreate approach does requires some programming skills; however, they are pretty minimal. The FME approach is relatively easy too, but it does require some familiarity with using FME. So, if you can decide which one to use, try them both and see which one works the best for you.
Monday, June 27, 2005
This type of data is not that unusual to have. For an example, let’s say we have an ASCII file of lighting strike information containing records with a time an X and Y coordinate of the strike. It turns out to be fairly simple to get this data into the GTViewer format. One of the benefits of using the GTViewer family of products is that you have a variety of methods for creating data in the GTViewer format. Safe Software’s FME is always an option in cases like this, but if you do not have FME or do not know some of the details of using it with custom formats, it may not be a desirable option. Another option is to use GTViewer’s or GTVx’s OLE Automation (and Visual Basic) to programmatically create any elements you need. And yet another option and the topic for this blog entry is to use GTCreate (one of the tools delivered with the GTViewer SDK).
The approaches for using GTViewer’s and GTVx’s OLE Automation and GTCreate to create data are very similar. In each case, you call a method to generate an element after specifying its symbology characteristics, an optional linkages, and optional embedded data. There are a few guidelines for deciding which tool to use for creating GTViewer data from a custom format. GTViewer and GTVx are good options if you need visual confirmation or any real-time graphical cues as the data is converted. Since both GTViewer and GTVx have display capabilities, they are more appropriate when some form of graphical user interaction or verification is required as part of the data creation. A deciding point here is that GTViewer does not required the GTViewer SDK to develop with whereas GTVx does; however, GTVx has significantly more functionality when it comes to creating data programatically. GTCreate does not have any display capabilities and is usually a better choice when converting large amounts of data where performance is more important. Although GTCreate is a fairly simple tool, it is very powerful and the basis for several of GTI’s conversion tools including the Smallworld, Geodatabase, and G/Technology converters.
To illustrate how to use GTCreate, let’s start with an ASCII data file with the following information on lightning strikes:
6/27/2005 12:42:27 PM, 457382.5, 1515628.5
6/27/2005 12:42:30 PM, 456551.0, 1515066.0
6/27/2005 12:42:47 PM, 457590.4, 1514540.2
Then in Visual Basic, create a form with a Command Button on it and a GTCreate control.
The code for the command button is shown below:
Private Sub Command1_Click()
Dim buffer As String
Dim xValue As Double
Dim yValue As Double
Dim dateValue As String
Dim id As Long
Dim row As Long
' open tabular data file
Open "c:\temp\lightning.txt" For Input As #1
' open GTViewer graphics file
id = GTCreate1.Create("c:\temp\lightning.gtg")
' Loop through each tabular record
row = 0
While Not EOF(1)
Line Input #1, buffer ' read line from file
pos1 = InStr(buffer, ",") ' find first comma
pos2 = InStr(pos1 + 1, buffer, ",") ' find second comma
' parse out data value
dateValue = Left(buffer, pos1 - 1)
xValue = Val(Mid(buffer, pos1 + 1, pos2 - pos1 - 1))
yValue = Val(Mid(buffer, pos2 + 1))
' Draw circle with embedded data at strike
GTCreate1.SetProperties id, 3, 2, 0 ' color, weight, style
GTCreate1.SetFill id, 1 ' fill circle
GTCreate1.SetData id, 1, "\tLightning\aId\v" + Str(row) + _
"\aTime\v" + dateValue
GTCreate1.AddCircle32 id, xValue, yValue, 25000
row = row + 1 ' increment row counter
' close files
This code is very simple. Most of it deals with reading the tabular file and parsing out the values. When this code is run, it produces a file called lightning.gtg. This is a regular GTViewer graphics file and it can be imported as redlines, used as a Category, or merged into an existing Category.
For simplicity, I will just import the .gtg file into GTViewer with Draw/Import and you will see the 3 circles for the lightning strikes:
Since data was embedded on the lightning strike circles, you can also review them with Attribute Info (with no additional effort):
This example is oversimplified, but I hope that it gives you an idea of the power and flexibility you have with a tool like this GTCreate.
Thursday, June 23, 2005
Let’s start with a simple report in Excel showing a list of Poles and various information including an X and a Y coordinate. Incidentally, this report was made with GTViewer’s Feature Counting command and pasted in Excel.
Activate the Visual Basic Editor in Excel by selecting Tools/Macros/Visual Basic Editor. Then add a new user form by selecting Insert/UserForm and call it UserForm1.
On your blank form, you need to place the GTVx control. By default, GTVx does not appear on the toolbox containing all of the controls you can place. Right mouse click on the toolbox and select Additional Controls and select GTVx. Place the GTVx control on the form. Then add the following code to the form to show the pole on the selected row in the Spreadsheet:
Private Sub UserForm_Initialize()
If GTVX1.OpenFile("c:\temp\demo.gtx") Then
r = Application.ActiveCell.Row
x = Application.ActiveSheet.Cells(r, 7) ' x position
y = Application.ActiveSheet.Cells(r, 8) ' y position
GTVX1.SetViewCenter 1, x, y, 350
This form is simply getting the X and Y values out of the selected row and then centering on the pole at a predetermined zoom level of 350. This code assumes you have a file called demo.gtx in your temp directory, but you could have used GTVx’s DownloadFile method to retrieve a file from the internet if not present, or accessed the file by a UNC name somewhere else on your network. GTVx currently has over 370 methods and captures over 40 events providing a very powerful development environment. However, with all of these methods available to you, it can be very simple to complete a specific task with only 2 methods as seen in this example.
To activate the Map from the spreadsheet, I placed a button at the top of the Report in the Spreadsheet and associated it with the following macro:
This macro just loads and shows the created above.
This may be a trivial use of GTVx, but I hope that it shows the power that GTVx can provide to your applications with minimal effort. GTVx can be placed in an existing application to provide map displays and access to your feature tabular information or an entirely new application can be built around it. For more information on developing with GTViewer and GTVx, see is previous Blog posting.
Wednesday, June 22, 2005
Version 4.0.x.19 of GTViewer is now available.
04.00.00.19 - 06/22/05
- NEW - Number of query slots has been increased from 50 to 100.
- NEW - Coordinate Factors values now displayed in Properties dialog.
- NEW - Locate XY will now accept four values in the X prompt and will do a fit.
- NEW - Feature Count Detail dialog will now show the X and Y for point features.
- NEW - New Methods -
- boolean OpenFile(BSTR filename);
- boolean Show(long value);
- boolean FromLatLong(double latitude, double longitude, long mode, double x, double y);
Tuesday, June 21, 2005
The Redline Symbols are found on the Redline Toolbar and on the Draw Menu.
Clicking on its toolbar button will display the Select Symbol dialog box shown below which support a variety of views.
The Select Symbol dialog is non-modal and can be left up while using GTViewer. Double-clicking the mouse on one of the symbols will activate the placement mode and the symbol will be attached to the cursor. While moving the symbol around with a mouse or stylus, it can be scale and rotated in various ways (rotation and scaling buttons are on the toolbar and the Shift Key plus an Arrow Key on the keyboard can be used).
A Symbol can be any character from any font defined in GTViewer’s .GTM file. The font can be a standard GTViewer font (.dfn file) or a TrueType font and can be a text font or a symbol font. The Symbols also support a fixed scale (so that they can automatically match the scale of other symbols already used in the data) ; however, they symbols can be scaled and rotated by the user at any time.
The symbols are defined in the .GTM file in the Symbols Section which defines a set of symbol groups and then the symbols that go into each group.
The Symbol Groups will be listed in the Symbol Selection dialog box in a combo box. Selecting a group in the combo box, will display only the symbols for that group. Grouping is an easy way to separate a large number of symbols so they are easy to find and out of the way if not used by a particular set of users.
A group must have a unique number (they do not have to be sequential) and you must have at least one group. Then for each group you define a set of symbols for it to include along with their placement properties. See the GTVConfig.doc file for details on defining a Symbols section in your .GTM file.
Saturday, June 18, 2005
- Windows CE 3.0
- Handheld PC 2000
- Pocket PC
- Pocket PC 2002
- Windows Mobile 2003 (sometimes called Pocket PC 2003)
- Window Mobile 2003 Second Edition
- Window CE .NET
There are 3 different setups for Pocket GTViewer to support these platforms:
1) The Handheld PC setup will support:
- Windows 3.0
- Handheld PC 2000
2 ) The standard Pocket PC setup will support:
- Pocket PC
- Pocket PC 2002
- Windows Mobile 2003 (sometimes called Pocket PC 2003)
3 ) The Windows Mobile setup will support:
- Window Mobile 2003
- Window Mobile 2003 Second Edition
- Window CE .NET
It is possible to install and run the Pocket PC setup version of Pocket GTViewer on a Windows Mobile 2003 Second Edition device; however, it will not take advantage of the two most important features of this version: Landscape mode and the Hi-Res mode. If your device does have a Hi-Res display (full VGA - 640x480), then you definitely want to use the Windows Mobile setup of Pocket GTViewer. The Hi-Res display will make your maps look stunning! Also, if you run the Pocket PC version on your Hi-Res screen, the lower resolution is emulated and will actually run slower. Most new devices sold run either Window Mobile 2003 Second Edition or Window CE.NET. Just having a Window Mobile 2003 Second Edition does not mean you have Hi-Res support, but you will have Landscape mode support which is sometimes useful for viewing map data.
Friday, June 17, 2005
Thursday, June 16, 2005
Most of the controls on this dialog are for formatting the range coordinate values.
You can select between Computed and System coordinates. For those who do not know the difference, Computed coordinates are the same are your data’s original coordinate system (whatever that may be). System coordinates are the values actually stored in the GTViewer format. Computed Coordinates are called “computed” because GTViewer runs the System coordinates through a computation to get the Computed values. You may ask why you would ever need the range in System coordinate values. Some of the parameters in the .gtm file and some of the data conversion utilities require System coordinates rather than Computed coordinates. Most of the methods used in development use either System or Computed, but there are some that do require system coordinates.
The range output is always specified as XLOW, YLOW, XHIGH, YHIGH; however, you can select the delimiter and and the number of digits shown after the decimal point.
The Copy button will take the text in the output box and copy it to the Windows Clipboard.
To see how this can be used, set the view as you like it and activate the Current View Extents dialog. Select System Coordinates and the Pipe Delimiter. Then Copy the result to the clipboard. In your .GTM file, you can paste the copied text in as the value for the Range entry:
When you open the .GTM file again, it will fit the data to these coordinates. This task is often performed when setting up data for the first time.
The GTExtract utility can also take a range as a parameter which can be obtained from the Current View Extents dialog. GTExtract will use either System or Computed coordinates (depending on the flag you use) and the coordinates are separated by a space delimiter.
You can also paste the range into the Locate XY dialog discussed in a previous Blog entry to locate on a particular range.
Wednesday, June 15, 2005
Tuesday, June 14, 2005
For this seemingly simple Dialog box, you get quite a few features and options:
- The Locate XY dialog can locate on either System coordinates are Computed coordinates. The mode is determined by the Coordinate Readout selected in the Options/Settings dialog. It is sometimes useful to be able to locate on system coordinates especially when you are setting up data for the first time or doing development.
- To save time keying in coordinates to locate on, you can key in both the X and Y in the X’s prompt. You can separate the values by a space, a comma, a semicolon, or a pipe.
- With version 4.0.x.19, you can key in four coordinates in the X’s prompt and a fit will be performed instead of a Locate. Use this feature in conjunction with View/Current View Extents as its output can be pasted directly into the Locate XY dialog.
- All changes to the view performed by the Locate XY dialog are recorded in the View History and are accessible with View/Location History.
- The Default Zoom setting in the dialog is defaulted to the DefaultZoomLevel entry in the [General Info] section of the .gtm file. The default is 500 if it is not set (and may likely be the wrong default zoom level).
- You can remove the Locate XY dialog from the Query menu by adding a LocateXYMenu=0 entry to the [Additional Properties] section of the .gtm file.
These features are really not hidden at all. They are all documented; however, most users do not take the time to research the non-obvious functionality of a simple feature like Locate XY. I hope this entry helps you get more use out of this simple tool.
Saturday, June 11, 2005
“Style” is a word that is probably used too much when describing aspects of GTViewer. There are linestyles, User-defined linestyles, symbol styles, element styles, and dynamic style. Dynamic styles are the type of styles dealt with by the Style Manager. A dynamic style is a Style Definition that is mapped to a particular Category Id/Filter Id pair for a particular zoom level range. A Style Definition defines all of the stylistic properties that can be used when rendering an element:
User-defined Linestyle Id
Origin Offset X
Origin Offset Y
Border Color Id
Border Color Value
Fixed Scale Flag
Extended Text Style Mode
Extended Text Style Weight
Extended Text Style Color Id
Extended Text Style Value
Some of these properties will apply to any type of element, and others will apply to specific elements. For example, Color Value will apply to all elements, while Font Id will only apply to Text and Symbol elements. When a Style Definition is applied to an element, any properties defined will override any of the corresponding properties embedded in the element.
A Style Definition is mapped to an element with a mapping rule that tells the Category and Filter Id of the elements (or feature class) and a zoom level range where the specified Style Definition will be used. Since you specify a zoom level range, you can have multiple Style Definitions mapped to the same feature and when the user zooms in or out, the style can change dynamically (hence the name “dynamic styles”).
In GTViewer, the Style Definition and Style Map files (usually called Style.def and Style.map) has been supported since Version 1.0. These files are simple ASCII files that look like the following:
[Switch - Large]
FilterMap2500041313Switch – Large
In the past, much of the data converted to the GTViewer format used Instance Based symbology which defines each element’s symbology directly on the element. The color, linestyle, font, etc. were all embedded into each graphical element. Framme, Field View, and Microstation data were the primary users of instance-based symbology. With Smallworld, Shapefiles , Geodatabases, and G/Technology, a different approach is generally taken by applying a style rule to a class of features. Also, with the recent addition of the GTViewer Reader/Writer plug-in to Safe Software’s FME, automatic conversions use the style based symbology approach by default (preparing the styles to be defined since FME does not actually convert the symbology information). GTViewer supports both instance based and style rule based symbology approaches and can use a combination of the two for maximum flexibility. In fact, if you have an Instance Based symbols dataset (such as a Framme dateset), you can usually get a much more usable display by applying a few Dynamic Styles to declutter the screen when zooming out, make certain feature emphasized, or change the printed output to better suite the medium (printing can use a different style definition and map than the display).
With the Style Rule based symbology approach being adopted more and more, it became apparent that a better way of creating the style definition and style mappings was needed. It is okay to edit a couple of text files when you only have 10 or so style definitions, but when you have 1000 or more (as many G/Technology datasets do), you need a better way to create and maintain the style information.
The Style Manager is a GUI tool built into GTViewer and is found under the Tools menu. This tool will allow you to interactively create, edit, delete, import, and export style definitions and style mappings. It has been evolving since GTViewer 3.0 and now provides a very powerful tool for managing your styles.
If you are currently editing the Style.def and Style.map files with notepad, stop immediately!!! The Style Manager is available and it is much to create or adjust styles with it than with notepad. Also, the Style Manager will lets you make adjustments to the styles in real time seeing immediately what affect they have on the data (no editing with notepad, closeing the dataset, and reopening it to see what the change was). Also, the Style Manager shows all of the features using a particular definition and which mappings were used to do it.
If you do not use Dynamic Styles with your dataset, the Style Manager is a good way to experiment in a non-destructive was to see if your displays or printed output can benefit from this feature. In general, you can improve the appearance with very little effort.
Take time to get to know the Style Manager if you are already using Dynamic Styles or would like to try them.
Monday, June 06, 2005
If nobody inferred this from what I just said, the number of query slots was increased from 50 to 100, therefore someone out there had a need for more than 50 query slots (and maybe more than one). I have noticed that more and more users are defining more and more queries and these long lists of queries sometime run off the screen. You can still select queries when the menu is bigger than the screen, it is just a pain to scroll the menu up and down to find the one you want. Back in version 4.0.x.9, a feature was introduced into GTViewer that allows you to build hierarchical menus in GTViewer, rather than the single level linear menus that have always been supported in the past. This new feature means that you can group queries and only show the group name on the Query menu. The group menu item will pop up the rest of the grouped items when it is selected. This feature is easier to show than to describe. Looking at the Electric/Gas sample data that is delivered with GTViewer, compare how a single level menu looks along side a hierarchical one:
Granted, this is a very small example, but if you have 30, 40, or 50 menu items, you can see pretty easily how the group will help. The best thing about grouping your menu items is how easy it is to do. Look below at the two versions of the [Query Info] section to see how the Electric and Gas groups were defined in the example above:
Single Level Menu:
**** Note: I couldn't get the blog to show the pipe symbol correctly, so I just put "[pipe]
Now with a 100 menu slots available, this feature will be more important than ever; however, even with a handful of queries, you may still find a use for this feature.