Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is...

20
Graphics, and more, with ABACO technology By Dott. Franco Cattafesta

Transcript of Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is...

Page 1: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Graphics, and more, with ABACO technology By

Dott. Franco Cattafesta

Page 2: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Drawings have been around a long time in computer science. Graphical problems in engineering and surveying, which share a common base in geometry, led to the development of PC CAD technology since the ‘80s. Nowadays, CAD users have scores of powerful tools and applications that help them produce accurate and informative drawings. Graphical interfaces are used to interactively trace lines and curves; geometric data may be read from text files, and then converted into graphical entities; data may also be obtained by analyzing scanned images, or digital pictures taken from aircraft or satellite. State-of-the-art, high-resolution peripherals give excellent visual feedback and printouts. CAD and GIS Along with technical improvements in hardware and software, CAD applications were soon extended beyond the actions of drawing and map printing, leading to the integration of graphical and textual information: a hybrid system containing both kinds of data is commonly referred to as a graphic database. This solution is widely used by municipal or government agencies dealing with land surveying, environmental resource management, property, town planning, and any other subject related to maps. These users most often visualize, print and analyze graphic files made by external consultants, but lack the instruments to automate such procedures, or to customize their analysis on both graphic and text data. Also, this information about public services could be made available through the Internet, thus reducing the need of direct communication with the offices and cutting on response times for most queries: but while displaying maps on Web sites is no big deal, linking them interactively to related data can be quite a job. The solutions to these problems require that the graphical nature of CAD be applied to geography and to the management of related data, making all components available for analysis and inquiry, both for the local and the remote user: a computer system for storing, manipulating and analyzing maps and geographic data is called GIS (Geographical Information System). In a GIS, geometric entities and properties represent anything that can be spatially referenced: thus, lines, polygons, lengths and areas may represent roads, land parcels, mileage, and taxable land. While the most common integration of graphics and data occurs in geography, this is not the only field of application. GIS software is flexible enough to treat any kind of data, provided it is spatially referenced: heating and sewage systems, crimes and suspects, cattle herds, even the human body, have all been mapped and analyzed. So the same considerations done on GIS may be applied, with due changes, to most graphic databases. Figure 1 shows a simplified conceptual image of a GIS.

Page 3: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Figure 1: outline of a GIS

Recently, I found myself facing graphic applications for the first time. I started with a typical GIS: a public system of maps, city boundaries and building sites, to be published in a municipal Web site. Other works I took were more of the geometrical kind, dealing with building blueprints and connectivity in power networks. As it often happens when facing new problems, I first had to face my own inexperience and explore the potential of such tools as Visual Basic and VBScript; another problem was the necessity to work both for the local and the distributed environment, with basically analogous problems, but different solutions. However, reality turned out to be not as bad as it seemed: all I needed was a tool that could join CAD technology, GIS, programming languages, and Web design. This is no mean feat, but such a tool exists, and it saved me a lot of time and effort. Handling drawings Most CAD software is bulky and expensive, and consequently unfeasible as a widely distributed solution, not to mention the added cost of customization. In many cases, especially when users don’t have specific graphic requirements, they need handy tools that allow editing and computations, and at the same time are easily inserted in other environments: the answer lies in ActiveX controls, which are designed for distribution and integration. I greatly benefited from such a component, which has scores of options and commands for the management of graphic entities: DbCAD dev, by Abaco (www.abacogroup.com). This OCX is easily combined with the data handling tools of standard languages such as Visual Basic, and can be used to develop applications and other ActiveX controls: it covers most drawing standards, and is flexible enough to help solve any GIS problem. To test the local environment, I wrote some examples using Visual Basic 6, and the 1.6 version of the DbCAD dev ActiveX control. Once installed, the control can be added to the list of components by right-clicking the Visual Basic Toolbox, choosing “Components”, and selecting “DbCAD dev” from the list of registered controls; it will then appear as a “Dbcocx” component. When dropped onto a form, DbCAD dev appears as a graphic window (the viewport) with a handful of buttons, which allow basic visual interaction; other actions are obtained by sending messages to the control during other events, such as menu or command button clicks. Figure 2 shows a Visual Basic project during construction.

Page 4: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Figure 2: Visual Basic form with DbCAD dev

Raster pictures The simplest images that can be displayed are raster pictures. A raster picture is actually a matrix of colored dots (or "pixels"), which can be produced with programs such as Paint, and stored in BMP (bitmap) files. The appearance and quality of the images we see in a raster picture are determined by its resolution: a high-resolution image has good quality and smooth lines, while with a low resolution (or by zooming in a picture) it is possible to see the individual pixels as squares. A raster picture is analogous to a video display, both being composed by a grid of pixels (the very term "raster" derives from the Latin word "rastrum", meaning "rake", and has also been used to describe the scanning process used in CRT technology), with the advantage that its size is independent from external factors, such as screen hardware and video drivers. Background drawing The management of graphic objects is done using a raster picture, which provides a physical base of pixels: each graphic object will be drawn on its corresponding group of pixels on the raster, which for this reason is called a "background". The background can be an actual picture, taken from a BMP file, or a virtual one, composed only by white pixels, in which case it will be called a "blank" raster.

Page 5: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Vectorial drawings In a raster picture, patterns can be detected visually, but cannot be managed as geometric entities: pixels are drawn independently from one another, and are not grouped into graphic objects, such as segments, circles, and the like. These entities, which form drawings usually handled with CAD programs, are also called "vectors" (hence the expression "vectorial drawings"). While raster pictures are fixed collections of pixels, vectors are characterized by their geometric properties: thus, a segment is identified by the coordinates of two points, and only when drawn it will be converted into pixels. Drawings come in a lot of formats, but at least in the engineering fields, the most used are DXF (Digital Exchange Format), SHP (ESRI ShapeFile), and DWG (AutoCAD drawing): DbCAD dev can import graphic files in all these formats, and export to DXF and SHP. Its internal engine relies on DBF graphic database tables, but any other format is supported. Calibration Images and drawings, representing actual systems, are referenced with coordinate systems set in "world" units, which depend on the subject of study and on the region to be displayed. The graphic window uses pixels, which are discrete entities, and are referenced with "screen" coordinates, measuring the distance from the left and upper margins of the viewport: their values are, by their very nature, non-negative integers, while, very likely, coordinates in a drawing will be in any range of real numbers (approximated by rational numbers). Furthermore, the "world", or "real", coordinate system normally has the x-axis pointing rightwards and the y-axis pointing upwards, whereas the "screen", or "physical", coordinate system has always the x-axis pointing rightwards and the y-axis pointing downwards. The proportional correspondence between the two coordinate systems is called calibration: after calibration, points in the graphic window will be shown, and referred to, with the chosen "real" coordinate system. Normally, a 2-point calibration is done, associating a rectangle in real coordinates to another in physical ones: this allows any axis orientation, but no rotations. Graphic database tables The basic geometric entities (or “vectors”) are POINT, LINE, CIRCLE, and ARC; a group of lines sharing the same identifier is called a POLYLINE, a variation of which is the POLYGON (a closed polyline identified by its vertexes). Vectors can be drawn in the graphic window once a background is present, and are stored in one or more DBF tables with a specific structure, which is the following: Field name Field type Width Decimals SECTION C 1 ID C 10 DESCR C 20 ECOLOR N 4 0 LAYER C 10 ELINE N 4 0 VX1 N 17 5 VY1 N 17 5 VX2 N 17 5 VY2 N 17 5 RAD N 17 5 TEXT C (variable) SECTION identifies groups of records, according to their use; in the examples, I will describe only the records pertaining geometric entities, which are identified by a value of “E” in this field. Normally, each entity is stored in one record of a graphic table (with the exception of polygons). ID is the entity identifier (actually, the primary key is on SECTION+ID). A unique ID is usually assigned automatically by DbCAD dev to each new entity; in

Page 6: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

the case of a polyline, however, it is necessary to force to same ID to a group of lines. DESCR describes the entity type (the geometric entities are POINT, LINE, CIRCLE, ARC, POLYGON, and VERTEX); in the case of a polygon, each VERTEX entity is stored in a record with a “P” in the SECTION field. ECOLOR contains the drawing color of the entity. LAYER contains the name of the layer to which the entity belongs. ELINE contains the drawing style. VX1, VY1, VX2, VY2, and RAD contain the geometric characteristics of the entity. The TEXT field is optional, but must be present when using certain non-graphic entities; its length is 10 by default, but can be set to any value. The other fields have different meanings for each graphic entity. In a POINT, VX1 and VY1 are the coordinates; in a LINE (which is actually a segment), VX1, VY1 and VX2, VY2 are the pairs of coordinates of the delimiting points; in a CIRCLE, VX1 and VY1 are the coordinates of the center, RAD is the radius; in an ARC, VX1 and VY1 are the coordinates of the center, RAD is the radius, VX2 and VY2 are the starting and ending angles, expressed in degrees. Now it’s the turn of some code: all the following examples assume that a Dbcocx object named “o” is present on a sample form. Example 1: calibrated raster background This example uses the following DbCAD dev methods: devDisplay Displays a BMP file devDisplayXY Displays a blank raster devZoom Sets zoom factor devCalibrate Changes coordinate system devGrOpen Opens a file to obtain graphic information devGrGetWidth Returns BMP width devGrGetHeight Returns BMP height The background is drawn with the "devDisplay" or "devDisplayXY" commands: devDisplay "" clears the graphic window (nothing is displayed) devDisplay <filename> displays the picture stored in the specified file devDisplayXY x, y displays a blank raster x by y pixels wide These commands clear the graphic window of any previous contents. In case a picture is already present in the graphic window, it may be desirable to reset the zoom factor at 100%, in case it has been modified: o.devZoom 100 A 2-point calibration is done as follows: o.devCalibrate p1, p2, p3, p4, p5, p6, p7, p8 The points (p1, p2) and (p5, p6) identify a rectangle in physical coordinates (on the graphic window), the points (p3, p4) and (p7, p8) identify a rectangle in real coordinates (on the raster picture). The picture can be calibrated with any orientation of the coordinate axes: the following snippet will set the point (0,0) at the lower-left corner of the picture, and orient the y-axis upwards. Since the picture cannot be expected to match the graphic window, its dimensions must be previously read from the BMP file: to get these data, the file, when it is opened with “devGrOpen”, is assigned a handle for future reference (devGrGetWidth, devGrGetHeight and devGrClose). The resulting image is shown in Figure 3.

Page 7: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Dim h As Long, x As Integer, y As Integer o.devzoom 100 o.devdisplay (App.Path + "\smoke.BMP") h = o.devgropen(App.Path + "\smoke.BMP") If h >= 0 Then x = o.devgrgetwidth(h) y = o.devgrgetheight(h) o.devgrclose h o.devcalibrate 0, y, 0, 0, x, 0, x, y End If Figure 3: Raster background image

Example 2: displaying a DWG file This example uses the following DbCAD dev methods: DevDrawDWG Displays a drawing as background DevGrCreate Creates an empty database table DevGrAppend Loads a drawing into the table DevGrDisplay Displays graphic database table contents DevUse Opens/closes database table A drawing (DXF or DWG) can be displayed as background, in which case it will be treated like a raster image, with no editing possible. It takes just one line of code:

Page 8: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

o.devDrawDWG App.Path + "\wheels.DWG" ‘ Display drawing as background In order to allow editing, the drawing must be loaded into a graphic database table. The amount of code is still minimal, as can be seen from the following snippet: o.devGrCreate App.Path + "\temp", 50 ‘ Create empty database table o.devGrAppend App.Path + "\wheels.DWG" ‘ Load a drawing into the table o.devGrDisplay ‘ Display the graphic entities Since the “devGrCreate” method erases the table, an existing database can be opened with another commands: o.devUse App.Path + "\temp", 50 ‘ Open a database table o.devGrDisplay ‘ Display the graphic entities To close the table, the “devUse” method must be called with an empty string as parameter (o.devUse ""). Of course, this should only be done when the table is not needed any more. Example 3: creating graphic entities This example uses the following DbCAD dev methods: devGetView returns viewport dimensions devGetPoint waits for user input (click in the graphic window) devLastKey detects mouse buttons used devGetPointDrag waits for user input (click in the graphic window) devGrCmdPoint stores a point into graphic database table devGrCmdLine stores a line into graphic database table devGrCmdCircle stores a circle into graphic database table devGrCmdPolyConv converts a polyline into a polygon devGetId reads entity ID from database table devGrDisplayId displays one graphic entity devGrDisplayXOR displays/hides one graphic entity devGetField reads a graphic attribute value devSetField writes a graphic attribute value First, some housekeeping must be done: clear the graphic window, create a graphic database table, and display a blank raster (filling the viewport). Normally, these actions can be done as the form is loaded (Load event): Private Sub Form_Load() o.devzoom 100 o.devgrclear 2 o.devcalibrate 0, 0, 0, 0, 1, 1, 1, 1 ‘ Reset coordinates o.devdisplay "" ‘ Clear window o.devgetview a, b, c, d, e, f o.devdisplayxy Abs(a - c), Abs(b - d) ‘ Blank raster o.devgrcreate App.Path + "\tmp", 20 ' Create empty graphic table End Sub Graphic entities can be identified visually, and their coordinates stored into memory variables with the method “devGetPoint”, which prompts the user to select a point by clicking on the viewport; the method “devLastKey” can then be used to detects which mouse button has been clicked. Another method that can be useful, when drawing a segment, is “devGetPointDrag”, which keeps a fixed point in the graphic window, and displays an elastic line from that point to the mouse location: this gives a visual clue of the final aspect of the new line. To detect the mouse button clicked by the user, the method “devLastKey” can be used as follows:

Page 9: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

o.devGetPoint “Choose a point”, x, y if o.devLastKey() = 13 Then ‘ 13=left button; 27=right button ... End If Once an entity is identified, it must be stored into the graphic database table, and each entity has its command: devGrCmdPoint "", x, y devGrCmdLine "", x1, y1, x2, y2 devGrCmdCircle "", x, y, r devGrCmdArc "", x, y, r, a1, a2 The first parameter is reserved for the entity ID; the others contain the geometric characteristics of the entity. The first parameter is to be left empty when ID assignation is left to DbCAD dev; otherwise, its value would become the ID of the new entity. For example, to force the same ID for all the components of a polyline, the first call should use the automatic ID assignment, after which the new ID can be read from the graphic database table; the other lines will be stored with that same ID. The following fragment shows a possible sequence (of course, this operation should be done in a loop): id = "" o.devgrcmdline id, x1, y1, x2, y2 id = o.devgetid() o.devgrcmdline id, x3, y3, x4, y4 I placed some command buttons on the form, each one firing a “Click” event to allow a graphic input; the user can choose a point, a line (which if identified by two points), a polyline, and a polygon (which is best input as a polyline, and then converted into a polygon). When an entity is stored into the graphic database table, it is necessary to display it (using the “devGrDisplayID” method, which singles out the entity to draw: this is obviously faster than redisplaying the whole drawing), because user input leaves no traces in the graphic window. Another display command is “devGrDisplayXOR”, which is basically the same as “devGrDisplayID”, but uses a “transparent ink” technique, which causes it to be hidden when it is displayed a second time (or an even number of times, for that matter): this allows such effects as animation (which can be useful in GPS applications) or temporary entities (for example, a snap symbol appearing when the mouse is rolled near some specific point). As an example, the “cmdAnimation” snippet is a crude animation of a circle: the location of the object, detected with the “devGetField” method, is changed between successive displays, storing the new value back into the table with the “devSetField” method. One thing to be noted is that those methods use string values, so some care must be taken when using numeric fields, as in the animation example with the coordinates of the center. Figure 4 shows the code of a sample form, and figure 5 shows a form with a polyline. Figure 4: adding graphic entities to a drawing Option Explicit '********************************************* ' OCX settings '********************************************* Private Sub Form_Load() Dim a As Double, b As Double, c As Double, d As Double, e As Double, f As Double o.devzoom 100 o.devgrclear 2 o.devcalibrate 0, 0, 0, 0, 1, 1, 1, 1 ' Reset coordinates o.devdisplay "" ' Clear window o.devgetview a, b, c, d, e, f o.devdisplayxy Abs(a - c), Abs(b - d) ' Blank raster

Page 10: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

o.devgrcreate App.Path + "\tmp", 20 ' Create empty graphic table o.devdrawdwg App.Path + "\wheels.dwg", 0, "" End Sub '********************************************* ' Displays a raster picture '********************************************* Private Sub cmdRaster_Click() Dim h As Long, x As Integer, y As Integer o.devzoom 100 o.devdisplay (App.Path + "\smoke.BMP") h = o.devgropen(App.Path + "\smoke.BMP") If h >= 0 Then x = o.devgrgetwidth(h) y = o.devgrgetheight(h) o.devgrclose h o.devcalibrate 0, y, 0, 0, x, 0, x, y End If End Sub '********************************************* ' Picks an entity, and then paints it red '********************************************* Private Sub cmdPick_Click() Dim x As Double, y As Double, id As String o.devgetpoint "Click on entity", x, y o.devsetaperture (20) ' Set a tolerance o.devgrseek x, y, 0 ' First graphical search If o.devfound() Then ' devFound() > 0: entity found id = o.devgetid() o.devgrdisplayid id, 1 ' Display in red End If End Sub '********************************************* ' Draws a point '********************************************* Private Sub DrawPoint() Dim x As Double, y As Double, id As String id = "" o.devgetpoint "Choose point (right click to abort)", x, y If o.devlastkey() = 13 Then o.devgrcmdpoint "", x, y id = o.devgetid() ' Retrieve point ID End If If id <> "" Then o.devgrdisplayid id, 256 End Sub '********************************************* ' Draws a line '********************************************* Private Sub DrawLine() Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double, id As String id = "" o.devgetpoint "Initial point (right click to abort)", x1, y1 If o.devlastkey() = 13 Then o.devgetpointdrag "Final point (right click to abort", x2, y2, x1, y1, 1 If o.devlastkey() = 13 Then o.devgrcmdline "", x1, y1, x2, y2 id = o.devgetid() ' Retrieve line ID End If End If If id <> "" Then o.devgrdisplayid id, 256 End Sub '********************************************* ' Draws a polyline '*********************************************

Page 11: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Private Sub cmdPolyline_Click() cmdPolyline.Enabled = False polyline cmdPolyline.Enabled = True End Sub '*********************************************************** ' Draws a polyline, then transforms it into a polygon '*********************************************************** Private Sub cmdPolygon_Click() Dim id As String id = polyline() o.devgrcmdpolyconv (id) o.devgrdisplayid id, 256 cmdPolygon.Enabled = True End Sub '********************************************* ' Actual polyline input '********************************************* Private Function polyline() As String Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double, id As String o.devgetpoint "Initial point (right click to abort)", x1, y1 If o.devlastkey() = 13 Then o.devgetpointdrag "Final point (right click to end)", x2, y2, x1, y1, 1 id = "" While o.devlastkey() = 13 o.devgrcmdline id, x1, y1, x2, y2 id = o.devgetid() o.devgrdisplayid id, 256 x1 = x2 y1 = y2 o.devgetpointdrag "Final point (right click to end)", x2, y2, x1, y1, 1 Wend End If o.devgrdisplayid id, 256 polyline = id End Function '********************************************* ' Generate a moving circle '********************************************* Private Sub cmdAnimation_Click() Dim id As String, a As Double, b As Double, c As Double, d As Double Dim r As Double, e As Double, f As Double, x As Double, y As Double o.devgetview a, b, c, d, e, f x = Abs(a - c) / 2 ' Place a circle in the middle y = Abs(b - d) / 2 ' of the viewport r = x / 4 o.devgrcmdcircle "", x, y, r id = o.devgetid() ' Retrieve circle ID o.devgrdisplayxor id, 256 ' Display with transparent ink ' i = 1 While i <= 20 o.devgrdisplayxor id, 256 ' Hide entity x = Val(o.devgetfield("vx1")) o.devsetfield "vx1", Trim(Str(x + 10)) o.devgrdisplayxor id, 256 ' Display in new position i = i + 1 Wend End Sub

Page 12: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Figure 5: a polyline in the viewport

Graphical searches Distances and spatial searches are usually present in geometric problems. The most common problem is when the user must snap to some entity, as, for example, when trying to connect a new line to an existing point, or when visually selecting an object: since the mouse click will probably be some pixels away from the target, an inspection of the surroundings is needed. The search may also be programmatic: if a drawing represents a power network, connected lines may not be perfectly matching their geometrical vicinity, because of drawing errors, so that trying to solve a connectivity problem may require searching points around a given one, rather than coincident points. In any case, a spatial search requires that, given a point, nearby entities be found. We can solve it by setting, with the “devSetAperture” method, a tolerance in pixels (say, 20 pixels, or the number of pixels corresponding to a given distance in world units), called “aperture”, then issuing a search command (devGrSeek); the search result can be tested with the “devFound” method, which returns 0 if no entity was found. The snippet is associated to a command button in the sample form: Private Sub cmdPick_Click() Dim x As Double, y As Double, id As String o.devgetpoint "Click on entity", x, y o.devsetaperture (20) ' Set a tolerance o.devgrseek x, y, 0 ' Search

Page 13: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

If o.devfound() Then ' devFound() > 0: entity found id = o.devgetid() ‘ Retrieve entity ID o.devgrdisplayid id, 1 ' Display in red End If End Sub When looking for all the entities that lie near a given point, we may loop through the database table by starting subsequent searches from the record reached (detected with “devRecno”), as follows: o.devgetpoint x, y o.devSetAperture (nAperture) ‘ Set a tolerance o.devGrSeek x, y, 0 ‘ First graphical search While o.devFound() ‘ devFound() > 0: entity found ... ‘ Other statements o.devGrSeek x, y, o.devRecno() ‘ Proceed searching Wend Other problems Snapping to a grid, building a polyline from existing connected segments, computing lengths and areas, moving and copying entities, setting multiple line styles, managing layers in a drawing: the list of problems is almost endless, and many are really tough. Yet, DbCAD dev offers a great number of graphical and database methods, making it possible to turn a drawing inside out and extract every information, in any form, thus satisfying most needs; of course, the amount of code required is much more than that of the few examples I wrote, but we all love the challenge of tackling difficult tasks. GIS on the Internet DbCAD dev is the engine of a client-server duo, also written by Abaco, that helps put GIS on the Internet. Installation requires a bit of planning: while most stuff (including DbCAD dev) goes into the system folder of the server, the publishing folder (the site “home directory”) requires the presence of the actual server interface (dbc_isapi.DLL), its configuration file (dbc_isapi.INI) and the client applet (dbCAD.class). Also, it will presumably contain a home page and other Web material, maybe organized in subfolders: the examples contain parts of a simulated municipal Web site (maps, cities, and some streets). The configuration file is a description of the view on the GIS contents: it contains, in text format, the names and locations of the files and database tables that are made available to remote users, and their display modes. The core of the GIS usually comprises a series of SHP files, which are a widely used standard for a combination of graphic and text information: each SHP file, in fact, is associated to a DBF file. One section of the configuration file, labeled [path], contains the name of the folder where the files are stored; another, labeled [shapes], contains the file names. The simplest configuration could be a plain list of “file” clauses, with a number sequence corresponding to the order in which the files are displayed, as follows: [path] SHAPES=c:\dbconline\shapes [shapes] file1=cities.shp file2=places.shp file3=streets.shp Text information can be extracted from the DBF files and displayed along with the graphic (which is probably the first reason for a GIS to exist): for example, a more complete image can be obtained by displaying the names of cities, places, and streets. This can easily be done by adding another entry for

Page 14: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

a given file, with a “layer” clause specifying which database field contains text information. The syntax includes a “DRAWTEXT:” keyword, as follows: file1=cities.shp file2=cities.shp layer2=DRAWTEXT:CITYNAME With the same numbering convention, other display clauses may specify other information: filling colors for polygons, font style for text data, line color and thickness, visibility options. The display may be further enhanced with a raster background: the usual choice is a group of ECW files, which contain geo-referenced images, that it, pictures (usually taken from aircraft) along with their spatial reference. This means that no option is necessary, since the images are displayed according to their geographic position. Data retrieval can be enhanced with links to any ODBC-compliant DSN, which can be queried via SQL-SELECT commands: this requires a few lines of another section, labeled [sqlserver], which specify the DSN connection and the fields to be used to join the tables. A complete configuration is shown in Figure 6. Figure 6: configuring the GIS A very plain configuration, with a folder for the ECW coverage, one for the shape files, and a DSN connection. The "color" clause specifies the drawing color of the shapefile; the "layer" clause specifies text information; in the [sqlserver] section, pertaining the DSN connection, the "Nome" field of the first shapefile will be linked to the "Name" field of the "Cities" table. [path] ECW=c:\dbconline\ecw SHAPES=c:\dbconline\shapes [shapes] file1 = cities.shp file2 = cities.shp layer2 = DRAWTEXT:NOME file3 = places.shp file4 = places.shp layer4 = DRAWTEXT:TOPO file5 = streets.shp file6 = streets.shp layer6 = DRAWTEXT:DENOMINAZI color1 = 1 [sqlserver] CONNECT="DSN=dbconline;UID=;PWD=;" SHAPEFIELD1=Nome SQLFIELD1=Name SQLTABLE1=Cities Programming the applet The applet can be placed anywhere in a Web document, specifying a minimum of parameters: the name of the server DLL, the coordinates of the center, and a zoom factor. This is an example: <applet code="dbcad.class" width="370" height="250" name="dbc" id="dbc"> <param name="dlltouse" value="dbc_isapi.dll"> <param name="xcenter" value="1605190"> <param name="ycenter" value="4961582"> <param name="zoomf" value="1">

Page 15: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

By default, the user can only zoom in (with the left mouse button) and pan (with the right mouse button); the applet offers fuller interaction through its methods, which can be called in code. Any additional object placed in the document, either with a “href” or a “onclick” clause, can be associated with an event that fires when the user clicks on it: the corresponding code will get the job done by sending appropriate messages to the applet. I wrote some examples using VBScript, which offers a good balance of simplicity, power and portability. Figure 6 shows the resulting Web document. Figure 7: DbCAD applet with event images

Zooming and panning To help the user in panning, I placed some icons (directional arrows, magnifying glasses, and other stuff) on the page: they are actually GIF or JPG images, and their “onclick” events fire VBscript functions, but any other choice of objects and code would do. To pan programmatically, a translation of coordinates is needed: we must first detect the coordinates of the point at the center of the applet, then change them according to the direction, and display the image around the new center. For example, to pan in the northwest direction, the central point must be

Page 16: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

“moved” to the left and up: we may place the new center at the upper left corner of the applet, or compute the lengths of the translation multiplying the width and height of the image by 1/2 (or any other factor). Similar considerations can be made for any other direction. Zooming is even simpler: a “zoom in” and a “zoom out” can be done, respectively, by doubling and halving the zoom factor, or setting it to a specific value. The implementation is straightforward and flexible, and needs just a handful of lines of code. I wrote a couple of slightly different solutions for both actions, which leave ample space for improvement and expansion. See figure 8. The methods that return the relevant data are: GetX(), GetY() Central point coordinates GetViewX1(), GetViewX2() Left and right limits GetViewY1(), GetViewY2() Lower and upper limits GetZoomf() Current zoom factor The methods that modify the view are: PanTo(x,y) Set a new central point (x,y) ZoomIn() Doubles current zoom factor ZoomOut() Halves current zoom factor ZoomTo(f) Set any zoom factor “f” Figure 8: zooming and panning Applet tag, HTML fragments and VBscript functions with some examples of zoom and pan actions. <applet code="dbcad.class" width="370" height="250" name="dbc" id="dbc"> <param name="dlltouse" value="dbc_isapi.dll"> <param name="xcenter" value="1605190"> <param name="ycenter" value="4961582"> <param name="zoomf" value="1"> </applet> <-- Links to VBScript code --> <input type="image" name="northwest" src="images/nw.gif" alt="North-West"> <input type="image" name="southwest" src="images/sw.gif" alt="South-West"> <input type="image" name="zoomin" src="images/zoomin.jpg" alt="Zoom in"> <input type="image" name="zoomout" src="images/zoomout.jpg" alt="Zoom out"> <script language="VBScript"> <!-- '***************************************************************************** ' Pan (solution 1: set new center in a corner) '***************************************************************************** sub NorthWest() document.dbc.PanTo document.dbc.GetViewX1(), document.dbc.GetViewY2() end sub '***************************************************************************** ' Pan (solution 2: compute new center coordinates from world dimensions) '***************************************************************************** sub SouthWest() dim height, width, xCenter, yCenter, applet set applet = document.dbc width = applet.GetViewX2() - applet.GetViewX1() height = applet.GetViewY2() - applet.GetViewY1() xCenter = applet.GetX() yCenter = applet.GetY() xCenter = xCenter - width / 2.0

Page 17: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

yCenter = yCenter - height / 2.0 applet.PanTo xCenter, yCenter end sub '***************************************************************************** ' Zoom (solution 1: explicit call to "ZoomIn" method, doubling zoom factor) '***************************************************************************** sub zoomin_OnClick document.dbc.ZoomIn() end sub '***************************************************************************** ' Zoom (solution 2: compute a relative zoom factor) '***************************************************************************** sub zoomout_OnClick document.dbc.ZoomTo(document.dbc.GetZoomF()/2) end sub --> </script> Information retrieval The applet can query the server for information about objects of the GIS: data can be retrieved either from the DBF tables associated to the SHP files, or from a DSN. By default, the query results are displayed in a frame or a HTML page named “info”, if present (otherwise, a new temporary HTML page named “info” will be generated). The default can easily be overridden in the configuration file by specifying one HTM document for a given shapefile in a section labeled “info”. The shapefile is identified by its ordinal number, as in the following example: [info] page1=infocity.HTM The applet must first be set to the “Info” status with a “SetCommand” method; after that, whenever the user clicks on an object belonging to a shapefile, the corresponding data are retrieved from the standard DBF and from any linked table. When designing a custom Web page for display, field names from either a standard DBF or a DSN table must be enclosed between two combinations of hash and underscore symbols (“#_” before, “_#” after). For example, the fragment #_LENGTH_# is the marker for the actual value of the field “LENGTH”. Figure 9 shows the coding; figure 10 shows an info Web page. Figure 9: information retrieval HTML fragment and VBScript function that set the applet to "Info", and a fragment of a possible custom HTML document: <input type="image" name="info" src="images/info.jpg" alt="Info"> <script language="VBScript"> <!-- '******************************************** ' Purpose: Set applet to "info" status '******************************************** sub info_OnClick document.dbc.SetCommand(1) end sub --> </script> <!-- from custom HTML --> <body> <tr> <td><font size=2>City</td> <td><font size=2>#_CITY_#</td>

Page 18: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

</tr> <tr> <td><font size=2>Code</td> <td><font size=2>#_CODE_#</td> <tr> <td><font size=2>Pop.</td> <td><font size=2>#_PEOPLE_#</td> </tr> </body> Figure 10: displaying information

Searching places Spatial searches can be automated with a couple of powerful methods. “DBFSearch” can be used if the query needs specific field values in a shapefile DBF (for example, the name of a city); for complex queries, which may involve connected DSNs, the “SQLSearch” method allows full use of any SQL-Select command. In the second case, any field of the dataset filtered from the DSN can be used to retrieve records from a given shapefile. After a successful search, the applet automatically pans and zooms, adjusting the image to accommodate all the selected objects. The methods that retrieve the data are: DBFSearch(n,s1) SQLSearch(n,s2,f) The parameters: n shapefile number s1 comparison string (e.g.: “Name=’PARIS’”) s2 SQL-select command (any valid SQL command) f field name that links DSN table and DBF file

Page 19: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

As in the previous examples, any customization or enhancement, be it in HTML or in VBScript, requires just a few lines of code, and most queries can be written with few hassles. Figure 11 shows the coding; figure 12 shows the applet after a successful query. Figure 11: looking for places on a map A simple query form, and examples for both search methods. <form id="search" name="search">City name to search <input type="text" name="text"> <input type="button" name="dbf" value=" DBF "> <input type="button" name="sql" value=" SQL "> </form> <script language="VBScript"> <!-- sub info_OnClick document.dbc.SetCommand(1) end sub '*************************************************************** ' Purpose: Locate a city by name in the DBF corresponding ' to shapefile 1 (cities) ' Inputs: city name is in textbox "text" of form "search" '*************************************************************** sub dbf_OnClick dim cSearch cSearch = "Nome=" & UCase( Document.search.text.value) document.dbc.DBFSearch 1, cSearch end sub '*************************************************************** ' Purpose: Locate a city by name in the ODBC DSN ' Inputs: city name is in textbox "text" of form "search" '*************************************************************** sub sql_OnClick dim cSearch cSearch = "select%20*%20from%20Cities%20where%20Name='" & UCase( Document.search.text.value) & "'" document.dbc.SQLSearch 1, cSearch, "Name" end sub </script> Blank spaces are represented by their hexadecimal ASCII code (%20), because some browsers truncate the string at the first space occurrence.

Page 20: Graphics, and more, with ABACO technology · graphic entities: DbCAD dev, by Abaco (). This OCX is easily combined with the data handling tools of standard languages such as Visual

Figure 12: displaying search results

CONCLUSIONS As it always happens, facing new tools and problems is never a walk in the park, but every developer knows it is inevitable: what we are looking for is anything that can make the transition process easier, and help save precious time. In my personal experience, I found DbCad dev and Visual Basic (with their HTML counterparts) to be a useful combination for the development of GIS applications: besides their simplicity, they offer the possibility to work with standard tools and standard data, without the need for complex and expensive products, which would also be quite underused. As my work proceeded, the comparison of different problems, contacts with expert users, and information gathered on other related topics, all contributed to obtaining satisfactory experience and knowledge. I could, for one thing, appreciate that the GIS world has room for lots of problems and solutions, few of which trivial; even more comforting was the conclusion that, though the approach may seem quite different from case to case, most CAD and GIS applications can be dealt with in similar ways. Another consideration is that government agencies are by no means the only recipients of GIS technology: engineering, construction, resource management, transportation, environmental studies, emergency planning, marketing, and many other sectors, can all benefit from a well-planned GIS solution.