CT301
FINAL
PROJECT REPORT
Degree BSc Computation and Geography
Student RN 99004279
Submission Date 01 May 2003
The method used to take glacial mass balance studies are changing. New technology in the form of robotic sampling and GPS (Global Positioning Systems) are revolutionising data capture. With the new data capture techniques new methods of displaying the data and interpreting the results need to be found. 3D Visualisation is one method of achieving the visual display of the data. This project is concerned with the production of a computerised system to visualise the data from two glacial surveys conducted in 1995 and 1996. Using object orientated design techniques and the evolutionary method for the implementation. Transformation of the data from its existing form then use of a database system to store the results after the conversion. The visualisation is created using OpenGL libraries and Visual Basic on the Microsoft Windows Platform. After an initial attempt to generate a TIN (Triangular Irregular Network) built from tessellated triangles was seen to be unsuitable, a terrain map was generated using the heights on sample points that are allocated a position in a 1024 by 1024 grid averaging out points that appeared in the same grid cell. The image system interpolated the points using a linear equation to interconnect the survey points.
Table of contents
Abstract 2
1. Introduction 5
1.1 Structure of the report 5
1.2 Background 5
1.3 Project Aims 5
1.4 Review of Relevant Literature 6
1.5 Deliverables 8
1.6 Overview of the project 8
1.7 Educational value 8
1.8 Technical challenge 9
2. Requirements 10
2.1 Functional requirements of the system 10
2.2 Non Functional Requirements 10
3. State of the Art 12
3.1 Existing Systems 12
3. 2 Choice of visualisation method 15
4. Design 16
4.1 Approaches and Notation 16
4.2 Conceptual Level Design 18
4.3 Communication of the design 20
5. Implementation 24
5.1 System Walkthrough 24
5.2 Examination of Important Routines 29
5.3 Switch to Visual Basic 33
6. Evaluation / Testing 34
6.1 Testing the system 34
6.2 Testing Against the Requirements 35
6.3 Evaluating the Approaches used 36
7. Conclusions and Further Work 37
7.1 Conclusions 37
7.2 Further work 37
8. Acknowledgements 39
9. Glossary of Terms 39
10. References 40
11. Table of Figures 41
Appendices 42
Appendices 42
Appendix A. Program Code 42
This chapter outlines the aims and gives an overview of the project being undertaken, identifying the work to be carried out. This chapter also provides an evaluation of the background reading and gives some initial ideas for a project solution.
1. Introduction - discusses the aims in greater depth, suggests the intended outcomes of the project, specifying the form that the deliverables of the project will take. This chapter discusses the learning objectives for the project and educational and technical value.
2. Requirements – states the requirements of the deliverable and project.
3. State of the Art - compares the aims of the project to existing systems and discusses the need for a new system.
4. Design - a detailed design of the system, considering some different possible approaches and details which will be used and why.
5. Implementation - provides a walkthrough of the system and examines how closely the design was followed and how the deliverable was created.
6. Evaluation/Testing - evaluates to what extent the deliverable fulfilled the requirements of the project and shows how the project was tested. This chapter also examines the approaches used in the project, and asks how successful they were.
7. Conclusions and Further Work - outlines the project and presents conclusions. Lessons learned from the project are discussed. Further extensions and improvements to the project are suggested.
Professor W F Theakstone provided data from two glacial studies, which used Global Positioning Systems (GPS) to record Northing, Easting coordinates along with Height data. The aim of the project is to use this data to create visualisations and make comparisons between the datasets. Two journal articles written by Professor Theakstone and provided with the datasets, explained the sampling methods used. They are examined in the next section.
The aim of the project is to develop a system to handle Easting, Northing and altitude data for the surface of a glacier and to generate a terrain model and/or visualisation. In the test data set there are two surveys from successive years, so changes will also be investigated between years.
The two journal articles ‘Digital Terrain Modelling of the Surface and Bed Topography of the Glacier Austre Okstindbreen, Okstindan, Norway’[1] and ‘Changes of snow cover thickness measured by conventional mass balance methods and by global positioning system surveying’[2] are the basis for the project. The second of these articles makes a comparison between the traditional methods and new techniques of glacial surveying using GPS (global positioning systems) devices. The article provides a good argument for the use of technology and explains both sampling methods in great detail.
The paper, ‘Digital Terrain Modelling of the Surface and Bed Topography of the Glacier Austre Okstindbreen, Okstindan, Norway’, focuses on the use of digital terrain modelling using TIN networks. It provides the base line from which any visualisation that is attempted needs to start and improve. The papers make use of height contour maps with the survey points marked.
A number of books concerned with the geographical aspects of the project were consulted, of which “Geographic Information Systems and Science”[3] proved particularly useful. Not only does it compare several methods of visualising GIS data, it also contains comparisons of different applications. It is well written and has some very good examples but at times can go into too much detail too soon. It also seems to require you to read it almost as if were a web page, constantly switching between the narratives on the page to the various inset boxes which explain a particular topic or give examples. Having said that, it is a very thoughtful text and has proved useful for my project.
Next are the books that explain the computing element of the project, namely the OpenGL graphics and the programming language guides.
Finally there is “Getting started with 3D - a designers guide to 3D graphics and illustration”[4], which is a primer on the art of 3D graphics, and details the methods of making a “good looking” visualisation. “Getting started with 3D” is not a book about programming. Rather it is about the art of creating a good visualisation. Focussing on computer graphics, the early chapters were especially useful in the descriptions of the art of 3D design, explaining perspective, the science of drawing and atmospheric effects. Later on in the book is a chapter about natural effects including terrain models (pages 60-64). The book provides a very detailed, yet easily comprehensible, synopsis of techniques that need to be considered when creating a 3D visualisation, and poses many interesting questions about creating a visualisation.
Also examined were a number of graphics
programming websites and books, which will now be discussed.
http://Nehe.gamedev.org[5] provided a wealth of OpenGL tutorials, information and ideas. The tutorials in particular are extremely comprehensive and cover in detail the sorts of methods needed to produce visualisations with OpenGL.
The book entitled “3D Graphics in Pascal”[6] proved of little use, since its main concern lay with creating line art through programming subroutines. While the mathematics used for the calculations was useful, it did not explain the usage in as comprehensive a way as the OpenGL programming guide. Also the book is rather outdated, being over 10 years old. Although the techniques described are still correct, their value has depreciated since graphical languages simplify graphics programming somewhat.
Microsoft’s online documentation for DirectX is fairly comprehensive and the software development kit (SDK) is freely available. However, Microsoft does not provide as extensive an archive of third-party tutorial sites and useful information as found on the OpenGL web page.
“OpenGL a primer”[7] is essentially akin to the first few chapters of the OpenGL programmer’s guide and is a fairly basic introduction to OpenGL libraries and techniques. The “OpenGL Programmer’s Guide” goes into far more depth and contains many examples of how and when to use OpenGL, some tutorials and useful programming tips.
OpenGL only provides a method of producing graphics so as to be cross platform, and therefore other languages are needed to create the windowing commands. Several languages that can be used with OpenGL were examined. These included C, C++, Java and Delphi. The book “Java - How to program”[8] is very useful, not just a primer to Java itself but also a primer on object orientated design and UML. It has an excellent use of teaching through example and colour coding of code and lettering. On the downside unfortunately, not all of the examples work or are complete (It is a book intended for use with university courses and there is a lecturer’s guide which completes some of the exercises).
The “C Programming Language”[9] is a seminal book describing the C programming language. It is concise (being by far the smallest of the programming reference guides), but it does not cover the windowing functions of C, instead concentrating on the different techniques available in the language. Overall it is a very good reference for C.
Microsoft’s “Visual C++ Programmer’s Guide” is not like the other programming books, since its primary aim is to show what Visual C++ version 6 can do and how it can be used, rather than teaching how to program in Visual C++. While it would be useful to show someone how to use Visual Studio, it is fairly useless for the project, at least until enough knowledge about C++ is gained to need a Visual Studio reference guide.
A program capable of the visualisation of a set of co-ordinates and height data for a given set of GPS data will be produced. Associated documentation will support the computing artefact. The program should also have the functionality either to export the data for use in a GIS system or be capable of calculating changes in volume between the visualised objects.
The main activities in this project are:
The test data for the project exists in the form of two Microsoft Excel spreadsheets.
An object-orientated approach will be taken to develop the system, as it offers a better path between the design and implementation than other models. This approach requires the use of object orientated tools. The program is intended primarily for the Microsoft Windows platform.
The required resources will include material regarding glacial environments, and literature on the programming languages. Other requirements include compilers, programming tools, operating systems and computers.
The development of the system deepens and expands the author’s knowledge in applying design techniques.
The author hopes to become fluent in new computer techniques, including the use of the OpenGL graphics environment and the C/C++ programming language. Likewise, there should be some improvement in management and organisational skills as a result of this project.
Furthermore, the project offers an opportunity to expand knowledge of glacial environments personally.
Development of a method of turning the raw information
comprising the global positioning data into a visualisation represents a
technical challenge. This will involve understanding the nature of
three-dimensional objects in OpenGL and C++. Adjusting to new languages is
always a challenge, and one that must be overcome in order to complete this
project successfully.
The requirements of the project are detailed in this chapter. These requirements were set entirely by the direct customer for the system, Dr. Roger Braithwaite.
The requirements cited below build upon the work undertaken by Professor W Theakstone in his glacial studies[10] of Austre Okstindbreen in Norway. Surveys of the glacier have been recorded in Excel spreadsheets, nominally at yearly intervals. Each data set consists of approximately 2000 survey points taken across much of the surface of the glacier. Each datum comprises of a date (optional) and values of Easting, Northing and metres above sea level.
The system must be able to read in the given data sets.
The system will need to be able to transform the information contained in the data sets into a form usable by the system to produce the visualisation.
Provide a visualisation of the GPS data sets.
Given a set of GPS points, the system should be able to display the points in space.
Calculations comparing the two datasets
The system should be able to perform mathematical operations on two (or more) data sets to compare and contrast the differences between them.
Ability to export data for use with GIS packages
Data used in the system should be able to be prepared for export to a GIS package.
The system should have a simple interface and be as user-friendly as possible.
Code and libraries for the system should aim to be as reusable as possible. This will enhance the portability of the system.
In its lifetime the system should be capable of being extended to include new algorithms for comparing the data sets.
Visualisation should complete in a reasonable amount of time
Rendering scenes can be time / processor intensive tasks. In
this system the visualisation should be accomplished quickly.
This chapter discusses the literature and materials that were used to determine how to proceed with the project. Alternative systems and methods are compared and evaluated.
The main task of the system is to visualise the data, and the other methods hinge around the choice of visualisation. There was a multitude of possible ways of tackling the problem of visualising the data, some of which form part of the discussion that follows.
Computer aided design packages are software designed to model and design objects in two or three dimensions. Popular CAD packages include AutoCAD, Microstation and 3D studio Max. CAD packages allow a great deal of flexibility in design and it would be possible to model the data sets in a CAD environment. CAD packages are not well suited to GIS environments as they use their own notation for positioning and placement rather than absolute co-ordinates, such as longitude and latitude. Indeed many GIS programs such as Intergraph’s Geomedia are a development of CAD packages, expanding the functionality to include special functions and using geo-referencing rather than proprietary units for measurement.
CAD systems produce views that are more akin to engineering drawings than pictures. What seems to be required here has more to do with a picture than an engineering drawing. While undeniably, what is done needs to be realistic, the primary emphasis is on visual appearance, not on accuracy as a quasi-engineering drawing from which other measurements can be derived.
Finally, mention should be made of the PV-Wave software from Visual Numerics, which is a system
designed to represent and produce contour
maps, and so would be more than capable of modelling the data sets.
Grid systems are systems
in which the data is put into a grid, from which interpolation can be used and
a graph of the data produced. The graph and grid data set can then provide a
source of information from which all kinds of calculations, including mass
balance, can be performed. Grided data sets, however, do not provide for the
most thrilling of graphical experiences, their appearance being more
utilitarian than aesthetically pleasing or in fact a representation of the actual
shape.
DEM (Digital Elevation Modelling) and DTM (Digital Terrain Modelling). These are methods used to display results from the Austria Glacier in Professor Theakstone’s article. DEMs use a grid structure on to which the heights at points on the grid are plotted. Once this has been done, lines can be drawn connecting the points together. This method estimates the heights of other points at regular intervals between the survey points by using interpolation. The accuracy can be improved by using splines (curved lines) rather than straight lines.
TINs (Triangular Irregular Network) are networks in which a surface is built up from interconnecting triangles. These are 2.5D (x, y and some z co-ordinates) surfaces composed of triangles. Each point of the triangle has special data for Easting and Northing data and attributing data giving the height of the point. TIN models also allow texture mapping, allowing, for example, a satellite image or aerial photography to be overlaid over the model.
Examples of a GIS system include Geomedia by Intergraph and Arcview from ERSI. Each of these systems could be used to perform operations on spatial data and then to produce either a DEM or TIN image of the data, allowing the overlay of a raster images producing to provide the visualisation with greater realism.
Graphics languages are specifically designed to represent and model graphics using code. Programming languages include OpenGL DirectX and also vector rendering engines such as Macromedia Flash.
One of the possible methods of visualising the data sets was to use Pascal. 3D graphics in Pascal were made possible by using pure programmatic techniques. Though it would be possible to execute in Pascal the visualisation would be limited. In fact Delphi (which is a visual language that uses Pascal as its base) has dropped the methodologies expressed in “3D Graphics in Pascal” in favour of using the OpenGL graphics library.
Direct X is Microsoft’s graphical language specifically designed for Windows programmers. Direct X was designed to give Windows the sort of abilities that OpenGL allowed in a native format. OpenGL was developed originally for the SGI IRIX platform. Direct X has many advanced functions, yet it has been mainly utilised by games programmers. There is a wealth of material regarding the Direct X API (currently at version 9) available from Microsoft. Unfortunately, although the software development kit is free, using Direct X would both tie the project to the Windows platform and to a certain extent dictate the use of Microsoft’s development tools.
Vector rendering platforms offer other possibilities in developing the project. Vector rendering is a method of building images from points, lines and areas, which makes it particularly suited to displaying the GPS data. In particular the emerging technologies of graphical mark-up language (GML), an offshoot of extensible mark-up language for graphics, could allow the creation of the visualisation in a browser. This would be inherently flexible as the Internet is mainly platform independent. However the standards are young and not fully formed. Also, browser-based systems would require a server that would add unwanted overhead. Furthermore, due to the interoperable nature of GML (it is parsed and run a line at a time) it could prove extremely processor hungry when compared to graphical programming languages that are more efficient.
OpenGL is a graphical language developed by Silicon Graphics to create a standard set of graphics libraries. These open graphic libraries were designed to be able to enable complex objects to be constructed around a number of primitives. OpenGL allows the production of 2 and 3 dimensional models and scenes. It also allows for lighting, perspective, viewpoints, atmospheric perspective shading and texturing.
The OpenGL libraries and tools have been ported from IRIX to virtually all versions of UNIX and Linux and also to Apple OS and Windows. However this cross platform nature leads to a minor problem. OpenGL has itself no windowing commands, so it requires another language such as C/C++ to create the windowing functions and make API calls to the operating system. This increases the learning curve somewhat since it would require the author to learn both OpenGL and a supporting language at the same time.
Method |
Advantages |
Disadvantages |
|
Adapt GIS system |
Less programming
involvement Built in methods of
calculations |
Possible limitations of GIS system Quality of the
visualisation might need to be sacrificed System would be tied to GIS package |
|
Use CAD package |
Good visualisation Less programming
involvement than new system |
Doesn’t use geographical references System would be tied to CAD package |
|
Bespoke new system |
Tailor made solution Most extensible choice |
Most amount of
programming Need additional features to interface with external packages |
Figure 1 Comparison table of methods
It was decided to use Open GL - an open and cross platform graphical language. It is extensible and should be able to output a very high quality visualisation of the data. Indeed it is used in many 3D packages because of its ability to produce high quality imagery. With Open GL though there is a need to program a system to input the raw data into Open GL. To do so, it was planned to use either C or C++ as they are both interface well with Open GL and can create code that is cross platform.
While this might be considered a “re-invention of the wheel” by implementing features already included in a GIS package, it does offer several advantages. Firstly a considerable amount of time might be spent on a GIS package, working against its limitations, as they are general systems, not specifically designed to solve this particular problem. Although a GIS package would provide many tools to analyse the data, it would not necessarily be the ideal one for the visualisation. 3D modelling packages would provide a very good visual output but would not have inbuilt tools to handle the calculations.
Secondly it would be prudent to develop towards a cross platform or portable system. It would be hard to do this by working with an existing proprietary product. For example, Arcview is one of the few programs that appear on more than one platform (Microsoft Windows).
Both OpenGL and C++ are object-orientated, suggesting that an object orientated design process be adopted. Object orientation allows better modelling of real world objects. Object orientation flows from the design to the implementation stage in a clearer manner than other methods such as the waterfall process model.
This section discusses some of the different methods that could have been used to design the system and comments on the choices made. A conceptual level design is presented together with a description of the design.
The problems the system design must overcome include: -
· Converting the GPS points into meaningful and useful data.
· Forming triangles from neighbouring points.
· Performing the visualisation.
· Comparison of different data sets mathematically.
· Exporting the resultant information.
The evolutionary method will be used, as the uncertainty of the project’s outcome is low but the complexity is high. The program will be built from modules that fulfil the different functions of the project, database, visualisation, import, compare and export. The modules will interact through a central application, which will have a standard windows interface.
Unified Mark-up Language (UML) will be used to explore the system design; the UML notation will then be used as a direct guide when building the system.
Currently the data is in the form of date, Northing, Easting, metres above sea level and time of sample. There are two sets in this form, each containing over 2000 results. The data is spatial in nature, which means it has slightly different characteristics from non-spatial data. Spatial data describes the real world. It has a structure dependent on the complexity of the object being represented, and therefore it can be large in volume, so storage considerations are important. Possible ways of storing the data are in a traditional flat file, use of the CSV documents as is, or in a database, either relational or object based.
These particular surveys and others could be loaded on to the system every time a visualisation is needed. However a better method would be to store the results in a database system. The decision to use a database allowed a wide range of standard functions to be accessed. Instead of having to program routines to manipulate the data, SQL statements can be used. Take, for example, a select query to recover all the points for a portion of the glacier over a certain height. In a flat file system functions to work with the data would have to be written. Using a database allows others to build queries and add new data to the system with comparative ease.
There are a number of different database systems that could have been used, from a home-grown one to a single user database engine, right up to a full blown one. Alternatives included: -
· mySQL
· Postgress
· Access
· MS-SQL Server
· Oracle
A home-grown system would need to be very complex and would mean that the tools that are freely available in database products would be absent.
The database systems can be split into two broad categories, firstly the open source products, mySQL and Postgress. Next are the commercial products, ranging from Microsoft Access, the standalone database, to the top of the range multi user systems from companies such as Oracle, IBM and Microsoft. Price considerations excluded MS-SQL Server and Oracle; Access might be too lightweight to deal with the data and would hinder a multi-user environment.
A reference is needed to recall the different studies, and although this search could be based on a time selection, this is a poor method given that the date field is not always present. Results can be taken on different days and time entries could contain noise, meaning they would be omitted. A better solution would be to add a survey field to each record so that all results for one survey could be easily traced without having to know the dates and times of the survey.
The system aims to emulate a standard Microsoft Windows interface, conferring several benefits to the application. The look and feel of a Windows program will be familiar to other programs that the users will have used and this will make the application conform to good HCI practice. The menus will have the familiar menu names; file operations will appear under a “File” menu. There will then be a menu to deal with the database operations, and a menu under which the visualisation options will appear.



Triangles will be constructed from groups of three neighbouring points; these triangles will the form a tessellated surface, the basis of the TIN matrix. Creation of the triangles will require the data to be converted into a more useful form. The data is spatial in nature, which means the x, y and z-axes are significant to the visualisation. To construct the visualisation in OpenGL, some sort of calculation to work out which points will form the primitives (the shapes that are used to build up the image) needs to be carried out.
In order to build the
triangles, a mechanism must be devised that will reference a particular point
with its nearest two neighbours. In order to achieve this, each point will be
assigned a unique identification tag. An initial reference point will be found,
and its two nearest points identified. The reference ID of the initial point,
and the IDs of its two nearest neighbours will be held in a separate database
table.
Table 1 contains the point’s data. Each point will be given a unique ID, which will also serve as the primary key for the table. Each point will have Northing, Easting, MASL (Metres Above Sea Level), time and date.
Table 1 Fields in the Point Table
|
ID |
Northing |
Easting |
MASL |
Time |
SurveyID |
Table 2 Fields in the Survey Table
|
surveyID |
Survey |
Table 3 Fields in the Neighbours table
|
ID |
Neighbour 1 |
Neighbour 2 |
The user is required to output the document into CSV format. This can be done simply from Excel (or any common spreadsheet package). This requirement was made in order to reduce the complexity, avoiding the use of an import filter for the Excel document, which would be extremely time consuming to write. Obtaining CSV output from Excel is simply a matter of changing one option in the Save menu dialogue; this is a fair request to ask of the user.
OpenGL has several methods of creating a surface. They share common features in that all OpenGL visualisations are built from vector primitives and can be overlaid with raster textures. The primitives available are points, lines and polygons (triangles or quadrilaterals).
The method adopted is to create a network of interconnecting triangles. The vertices of each triangle form a plane. A major problem is to devise a suitable mechanism whereby lists of survey points can be grouped together to create a tessellated network of triangles. This approach presumes that the survey points are more or less evenly distributed over the surface being modelled.
There are two mathematical methods of turning the points
into triangles, both of which have their strengths and weaknesses. The first is
to find the dot product (a · b ) of two vectors a and b, the method of
which can be seen here:
a · b = | a | | b | cos q
Assuming a = vector a, b = vector b, | a | = modulus of a, q = angle between them
If a = [x, y, z] and b = [e, f, g], where x and e, and y and f, and z and g are the scalar multipliers of the unit vectors i, j and k in the direction of the x, y and z-axes respectively,
a · b = ( x*e ) + ( y*f ) + ( z*g )
| a | | b | = Positive values of a (x + y + z) * Positive values of b (e +
f + g)
Therefore Angle (q) = cos-1 (((x*e) + (y*f) + (z*g)))
((x + y + z) * (e + f + g))
The alternative method is to use Pythagorean theory adapted to three dimensions to calculate the nearest distance between two points. This can be applied to find the two nearest neighbours belonging to any one point and so form a triangle.
The dot product of two vectors was a more precise calculation, also giving the angles of the vectors. However this level of detail comes at a price. The computing time required increases vastly over the time taken for the simpler Pythagorean equation. OpenGL itself will calculate the angles “on the fly” so storing them is unnecessary. On this basis the Pythagorean method with its lower computational and storage requirements is preferred. The results of the triangle calculation will be sorted in the database to be used in the creation of a triangular regular network.
In the database the list of points together with their neighbours will be stored. When a visualisation is requested all the points from a survey together with the relationships between the points will be retrieved.
Once the import routine was operable the data could be read into the system and manipulated to produce a visualisation.
Adapting one of the tutorials from Nehe[11] a visualisation of the sample points was produced (pictured below). This is an extremely simple picture displaying a triangle at each sample point on the visualisation. It did however highlight a major flaw in the method envisaged; the data was clumped at the top part of the glacier and very sparse further down the glacier. Producing a TIN matrix would be extremely difficult with this data and not very meaningful.

Figure 5 Visualisation of the Survey Points
The initial visualisation demonstrates that the data is unsuitable to create a TIN matrix; consequently a different method had to be found.
The alternative seemed to be to use an OpenGL technique called a height map, in which a rectangular grid is drawn of Easting and Northing. Heights are mapped on to the cells of the grid and plotted. Lines are then drawn joining the heights together. Usually height maps have values for every point on the grid. Unfortunately the sample would not cover every point on a grid. In fact, very few of the cells contain measured heights, producing a very sparse effect. The data could be estimated by linear interpolation to fill the intervening cells. This would plot most of the co-ordinates. Connecting them together forms a surface. This approach should create a more realistic looking surface given the recorded points of the data sets are not evenly distributed.

Figure 6 Graph Demonstrating the Sparse Spread of Survey Points
This chapter discusses the coding of the system in relation to the design chapter. The first section of this chapter provides a walkthrough of the system function, followed by a discussion of some of the more important routines in the system.
The first task is to add the data sets onto the system. The data sets must first be in comma separated variable format and contain four columns: date, Easting, Northing and MASL. The actual titles are not important, only the order in which the variables appear.
To import the file into the system the user first opens the system by double clicking the “Vglacier” icon. Next the user chooses open (Error! Reference source not found.) from the File menu; this pops up an Open file dialog box. The user is able to move through the directory structure and select a file to import (only *.csv files can be selected). Once a file is selected the Open button is clicked. A progress bar will appear and display the progress of the import. The import is complete when the progress bar reaches 100% and disappears.

Figure 7 Screen Shot - Opening a file for import
The user then has a choice, either to add the imported data set to the database or to visualise the imported data set.
To add the data to the database (assuming data has already been imported, the system will not allow database updating if there is nothing to add) first need to connect to the database. To connect to a database select “Connect” from the database menu a dialog box will appear (Figure 8 Screen shot – A Common Dialog box used to open a database (Figure 8) allowing the user to choose a Microsoft Access database to connect to.

Figure 8 Screen shot – A Common Dialog box used to open a database
Once a database connection is opened the dialog box disappears. The user needs to create a study to which the imported data is associated. Selecting “Manage Surveys” from the database menu a new dialog box (Figure 9) will appear. Existing surveys appear in the drop down box. Existing survey information can be edited by changing the text in the appropriate boxes. To add a new survey the user must click the “Add New” button.
This will bring another dialog box (Figure 10), the user needs to type in a survey name, date and comments are optional fields. Pressing “OK” add the new survey returning the user to the modify survey form. If any details are incorrect they can be modified here, otherwise cancel returns the users to the main menu.

Figure 9
Screen Shot - Manage Survey Dialog

Figure 10 Screen Shot - Add New Survey
The next step is to select “Update Database” from the Database menu. A new dialog box appears (Figure 11), using the drop down box to select the survey to update (the details of the survey will display once its selected). Pressing the “OK” button add the imported values to the survey and returns the user to the main menu. Pressing, “Cancel” returns the user to the main menu.

Figure 11 Screen Shot - Adding the imported values to the survey database
To display a visualisation first, data must be imported or a connection to a database containing survey data must be established (as per the proceeding instructions). Next selecting “Visualise Data” from the Display menu displays the visualisation source dialog (Figure 12). The first item to choose is the Source for the visualisation, either imported data or from a survey.

Figure 12 Screen Shot - Choose Data to Visualise
Note the options will be greyed out if a survey has not been imported or a database connected to. If displaying imported data click the radio button for imported data and then “OK”, the visualisation will be displayed. If displaying data from the database the user must click on the survey database this will make the survey dropdown box appear. Select the survey data using the drop down box, and press “OK” to launch the visualisation.

Figure 13 Screen Shot of a Visualisation

Figure 14 Screen Shot of a Visualisation Wire frame Mode
Left = Pan Left
Right = Pan Right
Up = Swivel Camera Down
Down = Swivel Camera Up
+ = Zoom In
- = Zoom out
Spacebar = Toggle Between Texture and Wireframe Modes
Escape = Quits to the main menu
For the visualisation to occur, first the data must be read into the system. Therefore the import routine is highly important. The data sets are both Microsoft Excel spreadsheets. The Excel file format is a proprietary close system and little could be done with the data in this form without resorting to application specific code. Excel does however offer the ability to export its files into other file formats, such as text and comma separated values. By exporting the data set to comma separated values it is instantly more valuable as a programming resource; the values are delimited by commas which do not occur in the data set itself. This allows the file to be parsed line by line and the information read into an array.
I originally wrote this routine in C++ and ported the code to Visual Basic after deciding to switch the language of implementation (see 5.3 Switch to Visual Basic).
After displaying the initial visualisation it became clear that there were the limitations with the data. There was a low density of sample points across much of the image, which meant that a TIN network would not produce a good visualisation. An alternative method would be to use a height map. It was possible to test quickly how well a height map would work for the data by using Microsoft Excel to draw a surface graph. Excels surface graph works much the same way as a height map and as the data is already in an Excel spreadsheet it could be produced easily. Using the data from the 1995 survey, the ranges of Easting and Northing were divided into a 32 by 32 grid. The survey points were mapped into the appropriate cell in the grid and the MASL value stored. Where a cell was occupied already, the average MASL was computed to replace the value stored previously. No interpolation was attempted, so the figure produced is made entirely from the survey points made. A 3-D surface was drawn using the chart tool in Excel.

Figure 15 - Graph of the 1995 Glacial Study using a 32 by 32 Grid
The MASL values plotted are scaled as a fraction of their range multiplied by 127.
i.e. MASL range = ( MASLmax - MASLmin )
Given a survey of a glacier consisting of a number of points (as Easting, Northing and MASL[12] values), a terrain map can be produced as follows:
At this stage the grid is sparsely populated, so it is necessary to fill in the gaps by linear interpolation, firstly by Easting and then Northing. This can be achieved as follows:
Consider the Northing values relating to a fixed Easting (E) with index 0, say.
I.e. grid (0, 0), grid (0, 1), grid (0, 2), and so on up to grid (0, 1023), where N ranges from 0 to 1023 and grid (E, N) contains an average value of MASL.
Suppose that values of MASL only exist for 4 cells: Grid (0, 6) grid (0, 29) grid (0, 123) grid
(0, 286)

Values for cells 7 to 28, 30 to 122 and 124 to 285 are estimated using linear interpolation.
The formulae used are given below and a similar diagram exists for traversing cells having the same Northing.
Height at n, hn = ha +
, where n lies between na and nb
Height at e, he = ha +
, where e lies between ea and eb

Figure 16 Graph showing the interpolation methodology
This was the first section written entirely in Visual Basic and linked to an Access database. The switch to using Microsoft Access negated the need to install another database system, as all the computers that will use the program have Jet (the Microsoft database management software) already installed.
The user has to choose a database to connect to, which can
be using a common dialog box which displays which databases are available.
During the implementation of the project many things did not go to plan. It took much longer than expected to get modules finished, fixing bugs and altering the design as it became apparent that the original methodology was not adequate.
A major change was to the testing. All the way through the process, the implementation code was tested as soon as it was ready. Data was run through and the results compared to what was expected. This meant that the testing and coding were in the most part carried out concurrently. This is was a saving grace since the coding took much longer than the budgeted time allowed.
As the project was not going to plan, the MoSCoW method was used to prioritise the requirements of a project concentration on the core requirements is possible.
During the implementation the system was moved from C++ to Visual Basic. This section attempts to show how and why the switch was made. The specification demanded that the system be primarily a Microsoft Windows application, and as such should have the same sort of look and feel to make it feel familiar to the user. In C++ this was not very easy to achieve. It was taking too long to write the visual interface. C++ was dropped in favour of Visual Basic since it is a Rapid Application Development Tool (RAD), originally designed as a prototyping language but now widely used as a tool of choice for creating Windows applications quickly. Menus, forms and buttons can be dragged and dropped into the application. The applications end up looking like other Windows applications as Visual Basic uses the standard Windows widgets (graphical objects such as toolbars and buttons). Users are much more comfortable learning programs if they behave in expected ways as with HCI foundations. Prior knowledge of Visual Basic development helped progress at an improved rate over the C++ development curve.
Visual Basic is an interpreted language, which causes it to perform slower than a C++ program, as each command is run line by line, being converted into machine code. It can also cause faults across different computers, as different speed computers queue and execute the instructions in different ways. These execution differences vary across different versions of Windows and chipsets and processors. Visual Basic is MS-Windows specific so it would rule out the possibility of making the application cross-platform. However being cross platform was not a requirement, simply a bonus feature.
This chapter evaluates the work done, then goes on to analyse the extent to which requirements were met. The last section discusses the methods used.
There was no formal testing plan as such, due to the visual nature of the project. The best test was the apparent correctness of the eventual visual output - if the visualisation looked like a glacier then it was deemed to be successful. Each module was tested for correctness.
Whilst working on the triangulation, a spreadsheet was created using 25 points to permit to investigate the behaviour of the nearest neighbour algorithm. The same 25 points were run through the program and the results compared with the spreadsheet. At first the values did not match up - a logical error was identified. This was quickly rectified, by slightly altering the loop structure responsible.
Although it functioned correctly, this module was not used in the final system because of the move to using a Height Map rather than a TIN model. Following this alteration, the triangulation module was no longer needed.
Validation routines strip out incomplete records and text as files are imported. A logical error was found in the validation code in the import stage. A loop counter was being increased where records were not added, resulting in the system recording a larger number of points. This caused some errors in some of the loop structures that ran out of points to process and introduced zeros into the calculations. The error only applied to creating triangles and producing the terrain map used imported data only.
During testing an error was discovered when files were opened. More specifically, while importing a selected file, an error occurred, crashing the program, if the Cancel button was pressed. Although the type of file was subject to validation, there was no validation on the Cancel event with the result that the program would try and load a file with a blank name. To fix this an extra validation rule was added to check the filename length was greater than zero. Additionally, a Common File Open dialog was used both to import files and to connect to a database. This could result in an error in the case of a file import after which the user attempts to open a database connection but cancels before choosing a file, where the system would attempt to open a database with the same name as the file being imported. To fix this the filename file was reset as soon as the common dialog box was called.
Data is checked for validity before being written to the database; incomplete records (missing Northing Easting or MASL) are rejected.
The functional requirements of the system were: -
The first three of these requirements were fully met; the system was able to read in both the 1995 and 1996 data sets. The system was able to the transform this and produce a visualisation. Unfortunately the system did not progress to the stage in which computerised comparison of data sets was possible. There are many reasons why the remaining requirements were not met. The overrun in the amount of time taken to produce the import routines and initial visualisation. Plus the time cost of switching the method used to visualise the object meant a choice had to be made as to what the focus of the project should be. The decision to concentrate on the production of the initial visualisation allowed the major requirements to be completed to a reasonable standard rather than rushing the entire project.
The Visual Basic Windows Application certainly has a higher usability than the C++ code would have allowed, mainly due the Visual Basic creating familiar buttons, and menus plus “tool tip” help on mouse hover over events. The data validation added means that the program prevents the user from inputting incorrect information and carrying out impossible operations (such as attempting to visualise a scene without choosing survey data).
The system is certainly modular enough to easily allow extensions to the system, the use of database is currently set up for Microsoft Access however the syntax commands would be the same only the database connection method would need altering. Using a database mean other modules can be built and use the shared data.
The quality of the visualised image was technically as high as the data would allow, however it did not look realistic enough and it was difficult to see the texture of the survey. This would require more advance lighting and texturing techniques such as bump mapping. Time did not allow for these methods to be incorporated however. The speed of image generation was a non-functional requirement; OpenGL needs to open a graphics subsystem to load before it renders the artefact, this causes a performance delay. Add to this the time taken to generate the image by the system and the total time to display the image is significant. The render time is about one minute (on an Intel Celeron 400mhz 640MB Ram, Nvidia Geforce II 32MB graphics card) this will depend on the system the program is running on. Though one minute is a reasonable long time in computer terms it once rendered the image can be manipulated in real-time.
Reusability of code was a stated requirement and this has been achieved to a high degree functions are called by different procedures using message passing raising the reusability level as high as possible.
Object orientated method of design was used; however for various reasons this proved to be less effective than the implementation method. While Object modelling was intended to help software designers more effectively model the real world, the model has a very steep learning curve and requires the designer to devote a lot of time analysing how the object structure could best map the real world problem. Another problem with the object orientated method appeared when the code base was moved to Visual Basic. Visual Basic 6 is not an object-orientated language; it is only object based. On the other hand C++ is a compiled language with faster execution times than Visual Basic, (assuming of course the code is well written - poorly written code will run slowly). Code can be compiled for a variety of platforms and operating systems. C++ is object oriented so fits well with the object orientated design process. This meant that the design did not map as neatly into Visual Basic code.
The system fulfilled many of the requirements of the project; a visualisation was produced from imported data. A database of survey results was generated and could be written to and read from.
While aware that the project had a high level of complexity at the start, it proved to be much higher than expected. The mathematics and programmatic structures needed to calculate the image vector and vertices proving particularly complicated.
The decision to use OpenGL had a number of consequences,
although the image quality OpenGL can produce is very high it proved to be a
very difficult medium to explore and exploit adding a great deal of time onto
the project implementation. The level of realism of the resultant image while
accurately mapping the information from the data sets did not display the
glacier surface with a high level of visible detail. Extra techniques to
enhance the image were possible, adding lighting effect, and bump mapping,
however these would have required a significant amount of extra work, both
adding code to the image generation process and working out the maths required.
Another improvement that could be made to the image is to add Texture mapping
to improve the visualisation of the terrain map.
Overall the use of OpenGL led to many problems and did not provide the sort of visualisation hoped for. That said the others methods available would have almost certainly had similar difficult problems and in the case of linking to a piece of third party software would have reduced the expandability of the project. OpenGL is a complex language and proved a difficult path to follow.
Although the switch to the height-map method of visualisation added a lot of time taken to complete that module that in turn meant the compare functions and export functions were not completed. However although the loss of these functions left a gap in the programs functionality the decision to omit them allowed a more comprehensive attempt at fulfilling the other requirements and which was a good choice of action as the parts of the project that were implemented worked well.
This proved to be a complex project with a difficult solution although the start of the project took the wrong direction, a good choice of implementation methodology allowed things to be turned around and a good solution achieved.
Apart from improving the quality of the visualisation the following problems could have been added.
An estimate of the volume of the solid displayed could be made as follows:
Each height (MASL) stored in the grid is associated with the same area, since dividing the ranges of Easting and Northing into 1024 equal parts formed the grid. For Example Take the 1995 Survey
Range of Easting = 8460.05;
Cell size (E) = 8460.05 ÷1024 = 8.26
Range of Northing = 7936.193
Cell size (N) = 7936.193÷1024 =
7.75
Area of cell = 8.26 x 7.75 units2 = 64 units2
Subtract the minimum value of MASL from each MASL value in the grid and form a sum. Then, multiply by the cross-sectional area of a cell. Even without the latter step, the sum is proportional to the volume of the figure.
Comparisons of different data sets could be made as follows:
Another possible
extension to the project would be to convert it C++ this would greatly improve
the executions times and it technically possibly. Much same structure could be
used with very little tweaking, indeed when code originally written in C++ was
converted to Visual Basic much of the structure was the same the main
difference being in the typing of variables. In any conversion the OpenGL code
would be almost exactly the same
Thanks to Roger Braithwaite for all his help, and to Andrew Conroy for all his programming tips, and advice.
API An application program interface (API - and sometimes spelled application programming interface) is the specific method prescribed by a computer operating system or by an application program by which a programmer writing an application program can make requests of the operating system or another application[13].
GIS Geographical Information System, a computerised system for working with spatial data.
GPS Global Positioning System, a satellite network which using a receiver, displays position with a high degree of accuracy.
HCI Human Computer Interaction, the link between the operator of the system and the system itself.
MASL Metres Above Sea Level, height recording using sea level as a baseline.
UML Unified Modelling Language, defines the components that will be used to build a systems and the interfaces that will connect is components[14]
SQL Structured Query Language, a high level programming language used with database systems.
TIN Triangular Irregular Network, a series of interconnection triangles arrange in a way to produce a continuous object or surface.
Angel, E (2002), ‘OpenGL a primer’ Addison-Wesley USA.
Ashford, J and Odam, J (1998), ‘Getting started with 3D a designers guide to 3D graphics and illustration’, Peachpit Press USA.
Bielig-Schulz, G
and Schultz, CH (1990) ‘3D Graphics in
Pascal’, Wiley England.
Deitel HM, Deitel, PJ (2002), ‘Java How to program 4th Edition’, Prentice Hall USA.
Eliens, A (2000), ‘Object-Oriented Software Development 2nd Edition ’, Pearson Education Ltd, Essex.
Kernighan, BW and Richie, DM (1988), ‘The C programming language 2nd Edition’, Prentice Hall USA.
Longley PA, et al (2001), ‘Geographic Information Systems and Science’, Wiley England.
Melofee, J (2003), ‘Neon Helium Productions Open GL Tutorials’, http://nehe.gamedev.net
Mirosoft Corporation, ‘Microsoft’s
DirectX Homepage’, http://www.microsoft.com/windows/directx/default.asp
Microsoft
Corporation, ‘MSDN DirectX Community’,
http://msdn.microsoft.com/community/directx.asp
OpenGL “The OpenGL Website”, http://www.opengl.org/
A great deal of information about OpenGL programming guides information news of the upcoming OpenGL 2 specification and links to many other OpenGL sites.
Pressman, R (2000), ‘Software Engineering A Practitioner’s Approach 5th Edition’, Magraw Hill.
Terrex, “Digital Terrain Modeling”, http://www.terrex.com
Theakstone WH, Jacobsen, FM (1997), ‘Digital Terrain modelling of the surface and bed topography of the glacier Austre Okstindbreen, Okstindan, Norway’ Geografiska Annaler 79A pp 201-214.
Theakstone, WH et al (1999), ‘Changes of snow cover thickness measured by conventional mass balance methods and by global positioning system surveying’, Geografiska Annaler 81A pp 767-776.
Whatis?com, ‘Whatis – Definitions for thousands of the most current IT-related
words.’, http://www.whatis.com/ Definitions for thousands of the most current IT-related words.
Woo, M et al (1999), ‘OpenGL programming guide: the official guide to learning openGL version 1.2 – 3rd edition’ Addison-Wesley USA.
Zaratian, B (1998), ‘Visual C++ 6.0 programmers guide’, Microsoft Press Redmond USA.
Figure 1 Comparison table of methods
Figure 5 Visualisation of the Survey Points
Figure 6 Graph Demonstrating the Sparse
Spread of Survey Points
Figure 7 Screen Shot - Opening a file for
import
Figure 8 Screen shot – A Common Dialog box
used to open a database
Figure 9 Screen Shot - Manage Survey Dialog
Figure 10 Screen Shot - Add New Survey
Figure 11 Screen Shot - Adding the imported
values to the survey database
Figure 12 Screen Shot - Choose Data to Visualise
Figure 13 Screen Shot of a Visualisation
Figure 14 Screen Shot of a Visualisation Wire
frame Mode
Figure 15 - Graph of the 1995 Glacial Study
using a 32 by 32 Grid
Figure 16 Graph showing the interpolation
methodology
This appendix contains some (but not all) of the code from the system, I have included the more important routine to give a flavour of the system.
Public Const gridSize = 1024
'Varibles use to read and error check input
Global ReadFile() As String
Global Northing() As Double 'Array of northing points
Global Easting() As Double 'Array of Easting Points
Global masl() As Double 'Array of meters abouve sea level
'Global sDate() As Long 'Array of dates
Global RecordCounter As Integer
Public conDB As ADODB.Connection 'Connection to database
Public adoRS As ADODB.Recordset 'Database recordset
Global dataOpen As Boolean 'Used to test whether the database is open
Global id() As Integer
Global survey() As String
Global SCounter As Integer
Global Current_Survey As Integer
Global dataImport As Boolean
Global Terrain(0 To gridSize - 1, 0 To gridSize - 1) As Byte
'intialise varibles
Public Sub main()
Let dataOpen = False
frmImport.Show
End Sub
Public Sub Read_Survey(mod_name As Object)
Dim i As Integer
Set rsSurvey = conDB.Execute("select * from survey")
SCounter = 0
' loop through the recordset adding items to the list box
Do While Not rsSurvey.EOF
SCounter = SCounter + 1
rsSurvey.MoveNext
Loop
ReDim id(1 To SCounter)
ReDim survey(1 To SCounter, 1 To 3)
rsSurvey.MoveFirst
For i = 1 To SCounter
'count the number of records in the database
id(i) = rsSurvey.Fields("surveyID")
survey(i, 1) = rsSurvey.Fields("surveyName")
If rsSurvey.Fields("surveydetails") <> "" Then
survey(i, 3) = rsSurvey.Fields("surveyDetails")
End If
If rsSurvey.Fields("sdate") <> "" Then
survey(i, 2) = rsSurvey.Fields("sdate")
End If
mod_name.cboSurveys.AddItem (survey(i, 1))
rsSurvey.MoveNext
Next i
'id and name must be completed so need need to test them
mod_name.txtSName.Text = survey(1, 1)
mod_name.txtComment.Text = survey(1, 3)
mod_name.txtDate.Text = survey(1, 2)
mod_name.cboSurveys.ListIndex = 0 ' default to the first survey
End Sub
Public Function Select_Survey(mod_name As Object) As Integer
mod_name.txtSName.Text = survey(mod_name.cboSurveys.ListIndex + 1, 1)
mod_name.txtDate.Text = survey(mod_name.cboSurveys.ListIndex + 1, 2)
mod_name.txtComment.Text = survey(mod_name.cboSurveys.ListIndex + 1, 3)
Select_Survey = id(mod_name.cboSurveys.ListIndex + 1)
End Function
'The number of points in each cell
Dim points(0 To gridSize - 1, 0 To gridSize - 1) As Integer
Dim grid(0 To gridSize - 1, 0 To gridSize - 1) As Double
Public Sub setpoint(east As Double, north As Double, masl As Double, minEast As Double, maxEast As Double, _
minNorth As Double, maxNorth As Double)
Dim e As Integer
Dim n As Integer
Dim tempE As Double
Dim tempN As Double
Dim range As Double
'Easting first
range = maxEast - minEast
range = 1.000001 * range
tempE = (east - minEast) / range
tempE = gridSize * tempE
e = Int(tempE)
'now northing
range = maxNorth - minNorth
range = 1.000001 * range
tempN = (north - minNorth) / range
tempN = gridSize * tempN
n = Int(tempN)
If grid(e, n) > 0 Then
grid(e, n) = ((grid(e, n) * points(e, n)) + masl) / (points(e, n) + 1)
Else
grid(e, n) = masl
End If
points(e, n) = points(e, n) + 1
End Sub
Private Sub countpoints()
Dim e As Integer
Dim n As Integer
Dim count As Long
count = 0
For e = 0 To gridSize - 1
For n = 0 To gridSize - 1
count = count + points(e, n)
Next n
Next e
count = 0
For e = 0 To gridSize - 1
For n = 0 To gridSize - 1
If grid(e, n) > 0 Then
count = count + 1
End If
Next n
Next e
End Sub
Public Sub makeGrid()
Dim i As Integer
Dim minN As Double
Dim minE As Double
Dim maxN As Double
Dim maxE As Double
Let minN = 1000000
Let minE = 1000000
Let maxN = 0
Let maxE = 0
Let minN = getMin(Northing)
Let minE = getMin(Easting)
Let maxN = getMax(Northing)
Let maxE = getMax(Easting)
frmProgress.ProgressBar1.Min = 0
frmProgress.ProgressBar1.Max = RecordCounter
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Min
frmProgress.ProgressBar1.Visible = True
frmProgress.txtName.Text = "Generating Grid"
frmProgress.Show
For i = 1 To RecordCounter
Call setpoint(Easting(i), Northing(i), masl(i), minE, maxE, minN, maxN)
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Value + 1
frmProgress.Refresh
Next i
frmProgress.Hide
End Sub
Public Function getMin(arr() As Double) As Double
Dim result As Double
Dim i As Integer
result = arr(1)
For i = 2 To RecordCounter
If arr(i) < result Then
result = arr(i)
End If
Next i
getMin = result
End Function
Public Function countNorth(n As Integer) As Integer
'Counts the number of points east for a given northing
Dim count As Integer
Dim i As Integer
Let count = 0
For i = 0 To (gridSize - 1) 'Move through the grid
If grid(i, n) > 0 Then 'test if a value occurs at each grid point
Let count = count + 1
End If
Next i
countNorth = count
End Function
Public Function countEast(e As Integer) As Integer
'Counts the number of points east for a given northing
Dim count As Integer
Dim i As Integer
Let count = 0
For i = 0 To (gridSize - 1) 'Move through the grid
If grid(e, i) > 0 Then 'test if a value occurs at each grid point
Let count = count + 1
End If
Next i
countEast = count
End Function
Public Function NextE(n As Integer, Start As Integer) As Integer
'Finds the Next Point along one grid line heading east in the grid
Dim i As Integer
Dim result As Integer
Let result = -1
'Do While i < gridSize And grid(i, N) = 0 'Test if a value found and if the edge of the grid is reached
' i = i + 1
'Loop
For i = Start To gridSize - 1
If grid(i, n) > 0 Then
result = i
Exit For
End If
Next i
NextE = result
End Function
Public Function NextN(e As Integer, Start As Integer) As Integer
'Finds the Next Point along one grid line heading north in the grid
Dim i As Integer
Dim result As Integer
Let result = -1
'Do While grid(E, i) = 0 And i < gridSize 'Test if a value found and if the edge of the grid is reached
' i = i + 1
'Loop
For i = Start To gridSize - 1
If grid(e, i) > 0 Then
result = i
Exit For
End If
Next i
NextN = result
End Function
Public Sub inTerPolate()
'Estimate the values of cells in the grid between the measured points
'Firstly in an easterly direction then northerly
'Negate the interpolated points so they can be determine from the measured ones
Dim e As Integer
Dim n As Integer
Dim i As Integer
Dim iFrom As Integer
Dim iTo As Integer
Dim STeps As Integer
Dim Interval As Integer
Dim HeightDiff As Double
Dim temp As Double
frmProgress.ProgressBar1.Min = 0
frmProgress.ProgressBar1.Max = gridSize + gridSize
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Min
frmProgress.ProgressBar1.Visible = True
frmProgress.Show
'East first
For e = 0 To gridSize - 1
count = countEast(e)
If count > 1 Then
Let STeps = 0
Let iFrom = 0
Do
Let iFrom = NextN(e, iFrom)
Let iTo = NextN(e, iFrom + 1)
STeps = STeps + 1
Interval = iTo - iFrom
HeightDiff = grid(e, iTo) - grid(e, iFrom)
For i = iFrom + 1 To iTo - 1
grid(e, i) = (i - iFrom) * HeightDiff / Interval + grid(e, iFrom)
Let grid(e, i) = -grid(e, i)
Next i
iFrom = iTo
Loop While STeps < count - 1
End If
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Value + 1
frmProgress.Refresh
Next e
'next north
For n = 0 To gridSize - 1
count = countNorth(n)
If count > 1 Then
Let STeps = 0
Let iFrom = 0
Do
Let iFrom = NextE(n, iFrom)
Let iTo = NextE(n, iFrom + 1)
STeps = STeps + 1
Interval = iTo - iFrom
HeightDiff = grid(iTo, n) - grid(iFrom, n)
For i = iFrom + 1 To iTo - 1
Let temp = grid(i, n)
grid(i, n) = (i - iFrom) * HeightDiff / Interval + grid(iFrom, n)
Let grid(i, n) = -grid(i, n)
If Abs(temp) > 0 Then
'Due to the fact points heights are geing averaged there might be a
'difference in height between the north and east grid lines
'so we are averaging out the height at the intersections
Let grid(i, n) = (Abs(temp) + Abs(grid(i, n))) / 2
Let grid(i, n) = -grid(i, n)
End If
Next i
iFrom = iTo
Loop While STeps < count - 1
End If
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Value + 1
frmProgress.Refresh
Next n
frmProgress.Hide
End Sub
Public Sub resetPoints()
'resets the negative values (used to differenciate calulated values)
Dim count As Long
Dim e As Integer
Dim n As Integer
For e = 0 To gridSize - 1
For n = 0 To gridSize - 1
grid(e, n) = Abs(grid(e, n))
If (grid(e, n) > 0) Then
count = count + 1
End If
Next n
Next e
End Sub
Public Function getMax(arr() As Double) As Double
Dim result As Double
Dim i As Integer
result = arr(1)
For i = 2 To RecordCounter
If arr(i) > result Then
result = arr(i)
End If
Next i
getMax = result
End Function
Private Sub MapTerrain(minMASL As Double, maxMASL As Double)
'MapTerrain scale the measured data so that they correspond
'to the height range of MASL.
Dim e As Integer
Dim n As Integer
Dim rangeMASL As Double
Let rangeMASL = maxMASL - minMASL
For e = 0 To gridSize - 1
For n = 0 To gridSize - 1
If grid(e, n) > 0 Then
Terrain(e, n) = _
Int(255 * (grid(e, n) - minMASL) / rangeMASL)
If (Terrain(e, n) > 255) Then
MsgBox "Terrain too big", vbOKOnly
End If
If (Terrain(e, n) < 0) Then
MsgBox "Terrain too small", vbOKOnly
End If
Else
Terrain(e, n) = 0
End If
Next n
Next e
End Sub
Public Sub genTerrain()
Dim minMASL As Double
Dim maxMASL As Double
minMASL = getMin(masl)
maxMASL = getMax(masl)
frmProgress.txtName.Text = "Interpolating Points Pass 1 of 2"
Call inTerPolate
Call resetPoints
'functions are recalled to cover any new points exposed
frmProgress.txtName.Text = "Interpolating Points Pass 2 of 2"
Call inTerPolate
Call resetPoints
Call MapTerrain(minMASL, maxMASL)
End Sub
Option Explicit
‘ This module is a modified version of tutorial 31 from http://nehe.gamedev.net
' a couple of declares to work around some deficiencies of the type library
' Problems are with the parameter declaration if someone wants to fix it
' I'd love to have a copy so I can remove these declarations
' I currently do not have the time to fix vbogl.tlb
'
' Please make sure that you have the type lib registered
' if you do not have a copy of vbogl.tlb
' you can get it here http://is6.pacific.net.hk/~edx/contents.htm
Private Declare Function EnumDisplaySettings Lib "user32" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As Long, ByVal iModeNum As Long, lpDevMode As Any) As Boolean
Private Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" (lpDevMode As Any, ByVal dwflags As Long) As Long
Private Declare Function CreateIC Lib "gdi32" Alias "CreateICA" (ByVal lpDriverName As String, ByVal lpDeviceName As String, ByVal lpOutput As String, ByVal lpInitData As Long) As Long
Private Const CCDEVICENAME = 32
Private Const CCFORMNAME = 32
Private Const HEIGHT_RATIO = 1.5
Private Const MAP_SIZE = 1024
Private Const STEP_SIZE = 8
Dim bRender As Boolean
Dim scaleValue As Single
'Private Const DM_BITSPERPEL = &H40000
'Private Const DM_PELSWIDTH = &H80000
'Private Const DM_PELSHEIGHT = &H100000
' DEVMODE declare used to query Windows for the
' Display device settings
' the one in the typelib has problems so I included this one.
Private Type DEVMODE
dmDeviceName As String * CCDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * CCFORMNAME
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type
Public Keys(255) As Boolean ' used to keep track of key_downs
Private hrc As Long ' handle for OpenGL redering context
Private fullscreen As Boolean ' are we in full screen
Private OldWidth As Long ' used to restore the starting display settings
Private OldHeight As Long ' Height
Private OldBits As Long ' bit per pixel
Private OldVertRefresh As Long ' and vertical refresh
Private mPointerCount As Integer ' maintains the number of show/hide cursor calls
Private xSpeed, ySpeed As Single
Private xAngle, yAngle As Single
Private Sub HidePointer()
' hide the cursor (mouse pointer)
mPointerCount = ShowCursor(False) + 1 ' how many times will we need to hide the pointer
Do While ShowCursor(False) >= -1 ' make sure it's hidden
Loop
Do While ShowCursor(True) <= -1 ' make sure the next call will show it
Loop
ShowCursor False ' one last time
End Sub
Private Sub ShowPointer()
' show the cursor (mouse pointer)
Do While ShowCursor(False) >= mPointerCount ' restore the cursor back to normal
Loop
Do While ShowCursor(True) <= mPointerCount
Loop
End Sub
Public Sub ReSizeGLScene(ByVal Width As GLsizei, ByVal Height As GLsizei)
' Resize And Initialize The GL Window
If Height = 0 Then ' Prevent A Divide By Zero By
Height = 1 ' Making Height Equal One
End If
glViewport 0, 0, Width, Height ' Reset The Current Viewport
glMatrixMode mmProjection ' Select The Projection Matrix
glLoadIdentity ' Reset The Projection Matrix
' Calculate The Aspect Ratio Of The Window
gluPerspective 45#, Width / Height, 0.1, 10000# '100#
glMatrixMode mmModelView ' Select The Modelview Matrix
glLoadIdentity ' Reset The Modelview Matrix
End Sub
Public Function InitGL() As Boolean
' All Setup For OpenGL Goes Here
glShadeModel smSmooth ' Enables Smooth Shading
glClearColor 0#, 0#, 0#, 0.5 ' Black Background
glClearDepth 1# ' Depth Buffer Setup
glEnable glcDepthTest ' Enables Depth Testing
glDepthFunc cfLEqual ' The Type Of Depth Test To Do
glHint htPerspectiveCorrectionHint, hmNicest ' Really Nice Perspective Calculations
InitGL = True ' Initialization Went OK
' xSpeed = 0.1 ' start with some movement
' ySpeed = 0.1
xSpeed = 1 ' start with some movement
ySpeed = 1
End Function
Public Sub KillGLWindow()
' Properly Kill The Window
If fullscreen Then ' Are We In Fullscreen Mode?
ResetDisplayMode ' If So Switch Back To The Desktop
ShowPointer ' Show Mouse Pointer
End If
If hrc Then ' Do We Have A Rendering Context?
If wglMakeCurrent(0, 0) = 0 Then ' Are We Able To Release The DC And RC Contexts?
MsgBox "Release Of DC And RC Failed.", vbInformation, "SHUTDOWN ERROR"
End If
If wglDeleteContext(hrc) = 0 Then ' Are We Able To Delete The RC?
MsgBox "Release Rendering Context Failed.", vbInformation, "SHUTDOWN ERROR"
End If
hrc = 0 ' Set RC To NULL
End If
' Note
' The form owns the device context (hDC) window handle (hWnd) and class (RTThundermain)
' so we do not have to do all the extra work
End Sub
Private Sub SaveCurrentScreen()
' Save the current screen resolution, bits, and Vertical refresh
Dim ret As Long
ret = CreateIC("DISPLAY", "", "", 0&) ' create display information context
OldWidth = GetDeviceCaps(ret, HORZRES) ' get the current width
OldHeight = GetDeviceCaps(ret, VERTRES) ' and current height
OldBits = GetDeviceCaps(ret, BITSPIXEL) ' and bits per pixel (color depth)
OldVertRefresh = GetDeviceCaps(ret, VREFRESH) ' and current refresh rate (this may cause problems in Win98
ret = DeleteDC(ret) ' delete the information context
End Sub
Private Function FindDEVMODE(ByVal Width As Integer, ByVal Height As Integer, ByVal Bits As Integer, Optional ByVal VertRefresh As Long = -1) As DEVMODE
' locate a DEVMOVE that matches the passed parameters
Dim ret As Boolean ' return value from api
Dim i As Long ' loop counter
Dim dm As DEVMODE ' Device mode
i = 0
Do ' enumerate the display settings until we find the one we want
ret = EnumDisplaySettings(0&, i, dm) ' get windows to enumerate the display settings
If dm.dmPelsWidth = Width And _
dm.dmPelsHeight = Height And _
dm.dmBitsPerPel = Bits And _
((dm.dmDisplayFrequency = VertRefresh) Or (VertRefresh = -1)) Then Exit Do ' exit when we have a match
i = i + 1
Loop Until (ret = False)
FindDEVMODE = dm
End Function
Private Sub ResetDisplayMode()
Dim dm As DEVMODE ' Device Mode
dm = FindDEVMODE(OldWidth, OldHeight, OldBits, OldVertRefresh) ' find our old display mode
dm.dmFields = DM_BITSPERPEL Or DM_PELSWIDTH Or DM_PELSHEIGHT ' what we are about to change
If OldVertRefresh <> -1 Then
dm.dmFields = dm.dmFields Or DM_DISPLAYFREQUENCY ' include vertical refresh
End If
' Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
If (ChangeDisplaySettings(dm, CDS_FULLSCREEN) <> DISP_CHANGE_SUCCESSFUL) Then
' If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
MsgBox "The Requested Mode Is Not Supported By Your Video Card", , "Fatal"
End If
End Sub
Private Sub SetDisplayMode(ByVal Width As Integer, ByVal Height As Integer, ByVal Bits As Integer, ByRef fullscreen As Boolean, Optional VertRefresh As Long = -1)
Dim dmScreenSettings As DEVMODE ' Device Mode
Dim p As Long
SaveCurrentScreen ' save the current screen attributes so we can go back later
dmScreenSettings = FindDEVMODE(Width, Height, Bits, VertRefresh) ' find a device mode that matches
dmScreenSettings.dmBitsPerPel = Bits ' set pixel bits
dmScreenSettings.dmPelsWidth = Width ' width
dmScreenSettings.dmPelsHeight = Height ' height
dmScreenSettings.dmFields = DM_BITSPERPEL Or DM_PELSWIDTH Or DM_PELSHEIGHT ' what we are going to change
If VertRefresh <> -1 Then
dmScreenSettings.dmDisplayFrequency = VertRefresh ' include vertical refresh
dmScreenSettings.dmFields = dmScreenSettings.dmFields Or DM_DISPLAYFREQUENCY
End If
' Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
If (ChangeDisplaySettings(dmScreenSettings, CDS_FULLSCREEN) <> DISP_CHANGE_SUCCESSFUL) Then
' If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
If (MsgBox("The Requested Mode Is Not Supported By" & vbCr & "Your Video Card. Use Windowed Mode Instead?", vbYesNo + vbExclamation, "Fatal") = vbYes) Then
fullscreen = False ' Select Windowed Mode (Fullscreen=FALSE)
Else
' Pop Up A Message Box Letting User Know The Program Is Closing.
MsgBox "Program Will Now Close.", vbCritical, "ERROR"
End ' Exit And Return FALSE
End If
End If
End Sub
Public Function DrawGLScene() As Boolean
' Here's Where We Do All The Drawing
glClear clrColorBufferBit Or clrDepthBufferBit ' Clear The Screen And The Depth Buffer
glLoadIdentity ' Reset The Current Modelview Matrix
If Keys(vbKeyLeft) Then Let yAngle = yAngle - ySpeed
If Keys(vbKeyRight) Then Let yAngle = yAngle + ySpeed
'If Keys(vbKeyAdd) Then xAngle = xAngle + xSpeed
'If Keys(vbKeySubtract) Then xAngle = xAngle - xSpeed
If Keys(vbKeyAdd) Then scaleValue = scaleValue + 0.001
If Keys(vbKeySubtract) Then scaleValue = scaleValue - 0.001
'If Keys(vbKeyUp) Then scaleValue = scaleValue + 0.001
'If Keys(vbKeyDown) Then scaleValue = scaleValue - 0.001
If Keys(vbKeyUp) Then xAngle = xAngle + xSpeed
If Keys(vbKeyDown) Then xAngle = xAngle - xSpeed
If Keys(vbKeySpace) Then bRender = Not bRender
Call glRotatef(xAngle, 1, 0, 0)
Call glRotatef(yAngle, 0, 1, 0)
' Call glRotatef(yAngle, 0, 0, 1)
' Call glRotatef(xAngle, 0, 0, 1)
'Call glTranslatef(0#, 0#, -5000)
Call gluLookAt(212, 60, 194, 186, 55, 171, 0, 1, 0) 'This Determines Where The Camera's Position And View Is
Call glScalef(scaleValue, scaleValue * HEIGHT_RATIO, scaleValue)
Call RenderHeightMap ' Render The Height Map
'Call triangles
DrawGLScene = True ' Everything Went OK
End Function
Public Function CreateGLWindow(frm As Form, Width As Integer, Height As Integer, Bits As Integer, fullscreenflag As Boolean) As Boolean
Dim PixelFormat As GLuint ' Holds The Results After Searching For A Match
Dim pfd As PIXELFORMATDESCRIPTOR ' pfd Tells Windows How We Want Things To Be
fullscreen = fullscreenflag ' Set The Global Fullscreen Flag
If (fullscreen) Then ' Attempt Fullscreen Mode?
SetDisplayMode Width, Height, Bits, fullscreen
End If
If fullscreen Then
HidePointer ' Hide Mouse Pointer
frm.WindowState = vbMaximized ' make the form big
End If
pfd.cColorBits = Bits ' color depth
pfd.cDepthBits = 16
pfd.dwflags = PFD_DRAW_TO_WINDOW Or PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER
pfd.iLayerType = PFD_MAIN_PLANE
pfd.iPixelType = PFD_TYPE_RGBA
pfd.nSize = Len(pfd)
pfd.nVersion = 1
PixelFormat = ChoosePixelFormat(frm.hDC, pfd)
If PixelFormat = 0 Then ' Did Windows Find A Matching Pixel Format?
KillGLWindow ' Reset The Display
MsgBox "Can't Find A Suitable PixelFormat.", vbExclamation, "ERROR"
CreateGLWindow = False ' Return FALSE
End If
If SetPixelFormat(frm.hDC, PixelFormat, pfd) = 0 Then ' Are We Able To Set The Pixel Format?
KillGLWindow ' Reset The Display
MsgBox "Can't Set The PixelFormat.", vbExclamation, "ERROR"
CreateGLWindow = False ' Return FALSE
End If
hrc = wglCreateContext(frm.hDC)
If (hrc = 0) Then ' Are We Able To Get A Rendering Context?
KillGLWindow ' Reset The Display
MsgBox "Can't Create A GL Rendering Context.", vbExclamation, "ERROR"
CreateGLWindow = False ' Return FALSE
End If
If wglMakeCurrent(frm.hDC, hrc) = 0 Then ' Try To Activate The Rendering Context
KillGLWindow ' Reset The Display
MsgBox "Can't Activate The GL Rendering Context.", vbExclamation, "ERROR"
CreateGLWindow = False ' Return FALSE
End If
frm.Show ' Show The Window
SetForegroundWindow frm.hWnd ' Slightly Higher Priority
frm.SetFocus ' Sets Keyboard Focus To The Window
ReSizeGLScene frm.ScaleWidth, frm.ScaleHeight ' Set Up Our Perspective GL Screen
If Not InitGL() Then ' Initialize Our Newly Created GL Window
KillGLWindow ' Reset The Display
MsgBox "Initialization Failed.", vbExclamation, "ERROR"
CreateGLWindow = False ' Return FALSE
End If
CreateGLWindow = True ' Success
End Function
Sub GLmain()
'Set up the values to do with key bindings
Let scaleValue = 0.15 ' Scale Value For The Terrain (NEW)
Let bRender = True 'wirefram or textured object
Dim Done As Boolean
Dim frm As Form
Done = False ' we're not done yet
' Ask The User Which Screen Mode They Prefer
fullscreen = MsgBox("Would You Like To Run In Fullscreen Mode?", vbYesNo + vbQuestion, "Start FullScreen?") = vbYes
' Create Our OpenGL Window
Set frm = New frmVisualise ' create our form
If Not CreateGLWindow(frm, 800, 600, 16, fullscreen) Then
Done = True ' Quit If Window Was Not Created
End If
Do While Not Done
' Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
If (Not DrawGLScene Or Keys(vbKeyEscape)) Then ' Updating View Only If Active
frm.Visible = False
Call KillGLWindow
Unload frm ' ESC or DrawGLScene Signalled A Quit
frmImport.Show
Else ' Not Time To Quit, Update Screen
SwapBuffers (frm.hDC) ' Swap Buffers (Double Buffering)
DoEvents
End If
If Keys(vbKeyF1) Then ' Is F1 Being Pressed?
Keys(vbKeyF1) = False ' If So Make Key FALSE
Unload frm ' Kill Our Current Window
Set frm = New frmVisualise ' create a new one
fullscreen = Not fullscreen ' Toggle Fullscreen / Windowed Mode
' Recreate Our OpenGL Window
If Not CreateGLWindow(frm, 640, 480, 16, fullscreen) Then
Unload frm ' Quit If Window Was Not Created
End If
End If
Done = frm.Visible = False ' if the form is not visible then we are done
Loop
' Shutdown
Set frm = Nothing ' destroy our form
End Sub
Private Sub triangles()
Dim i As Integer
Dim X As Double
Dim Y As Double
Dim z As Double
Dim q As Integer
Dim points(1 To 2250, 1 To 3) As Double
'Global array dosnt work so create a local one and insert values from local array
For i = 1 To RecordCounter
Let points(i, 1) = Northing(i)
Let points(i, 2) = Easting(i)
Let points(i, 3) = masl(i)
Next i
glBegin bmTriangles
Let X = 469400
Let Y = 7324955
Let z = 776
For i = 1 To RecordCounter
glColor3f 1#, 0#, 0#
Call glVertex3f(X - points(i, 1), Y - points(i, 2), z - points(i, 3))
Call glVertex3f(X - points(i, 1) + 50, Y - points(i, 2), z - points(i, 3))
Call glVertex3f(X - points(i, 1), Y - points(i, 2) + 50, z - points(i, 3))
'Using the global array dosnt work, no idea why
' Call glVertex3f(x - Northing(i), y - Easting(i), z - Masl(i))
' Call glVertex3f(x - Northing(i) + 50, y - Easting(i), z - Masl(i))
' Call glVertex3f(x - Northing(i), y - Easting(i) + 50, z - Masl(i))
Next i
glEnd
End Sub
Private Sub RenderHeightMap()
Dim XX As Integer 'Create Some Variables For Readability
Dim YY As Integer
Dim X As Integer
Dim Y As Integer
Dim z As Integer
Let XX = 0
Let YY = 0
glShadeModel (smSmooth)
If bRender Then ' What We Want To Render
glBegin bmQuads ' Render Polygons
Else
glBegin bmLines ' Render Lines Instead
End If
For XX = 0 To MAP_SIZE Step STEP_SIZE
For YY = 0 To MAP_SIZE Step STEP_SIZE
' Get The (XX, YY, Z) Value For The Bottom Left Vertex
X = XX
Y = Height(XX, YY)
z = YY
' Set The Color Value Of The Current Vertex
Call SetVertexColour(X, z)
Call glVertex3i(X, Y, z) 'Send This Vertex To OpenGL To Be Rendered (Integer Points Are Faster)
' Get The (XX, YY, Z) Value For The Top Left Vertex
X = XX
Y = Height(XX, YY + STEP_SIZE)
z = YY + STEP_SIZE
' Set The Color Value Of The Current Vertex
Call SetVertexColour(X, z)
Call glVertex3i(X, Y, z) ' Send This Vertex To OpenGL To Be Rendered
' Get The (XX, YY, Z) Value For The Top Right Vertex
X = XX + STEP_SIZE
Y = Height(XX + STEP_SIZE, YY + STEP_SIZE)
z = YY + STEP_SIZE
' Set The Color Value Of The Current Vertex
Call SetVertexColour(X, z)
Call glVertex3i(X, Y, z) ' Send This Vertex To OpenGL To Be Rendered
' Get The (XX, YY, Z) Value For The Bottom Right Vertex
X = XX + STEP_SIZE
Y = Height(XX + STEP_SIZE, YY)
z = YY
' Set The Color Value Of The Current Vertex
Call SetVertexColour(X, z)
Call glVertex3i(X, Y, z) 'Send This Vertex To OpenGL To Be Rendered
Next YY
Next XX
glEnd
Call glColor4f(1#, 1#, 1#, 1#) ' Reset The Color
End Sub
Private Function Height(XX As Integer, YY As Integer) As Integer ' This Returns The Height From A Height Map Index
Dim X As Integer
Dim Y As Integer
X = XX Mod MAP_SIZE ' Error Check Our x Value
Y = YY Mod MAP_SIZE ' Error Check Our y Value
Height = Terrain(X, Y) ' Index Into Our Height Array And Return The Height
End Function
Private Sub SetVertexColour(X As Integer, Y As Integer)
' Sets The Color Value For A Particular Index, Depending On The Height Index
Dim rcolour As Single
Dim gcolour As Single
Dim bcolour As Single
Dim Correction As Single
Let Correction = 0.15
Let rcolour = (Correction + Height(X, Y) / 256#)
Let gcolour = (Correction + Height(X, Y) / 256#)
Let bcolour = (Correction + Height(X, Y) / 256#)
' Assign This Blue Shade To The Current Vertex
Call glColor3f(rcolour, gcolour, bcolour)
End Sub
Private Sub Form_Load()
dataImport = False
End Sub
Private Sub mnuAboutInfo_Click()
frmAbout.Show
End Sub
Private Sub mnuDatabaseConnect_Click()
Dim result As Integer
Let result = 0
If dataOpen = True Then
result = MsgBox("Database Already Open Change Database?", vbOKCancel, "Information")
If result = 1 Then
Call openData
End If
Else
Call openData
End If
End Sub
Private Sub openData()
cdgImport.filename = ""
cdgImport.Filter = "Microsoft Access Databases |*.mdb"
cdgImport.ShowOpen
Set conDB = New ADODB.Connection
Set adoRS = New ADODB.Recordset
If Len(cdgImport.filename) > 0 Then
'test if a file selected before attepting to open
With conDB
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source = " & cdgImport.filename
.Mode = adModeReadWrite
.Open
End With
dataOpen = True
End If
End Sub
Private Sub mnuDatabaseSurvey_Click()
If dataOpen = True Then
dlgSurvey.Show
Else: MsgBox "Please Connect to a datasource", vbCritical, "Warning No Database Found"
End If
End Sub
Private Sub mnuDatabaseUpdate_Click()
If dataOpen = True Then
If dataImport = True Then
dlgUpdate.Show
Else: MsgBox "No data to add please import a survey", vbCritical, "Warning Nothing to Do"
End If
Else: MsgBox "Please Connect to a datasource", vbCritical, "Warning No Database Found"
End If
End Sub
Private Sub mnuDisplay3d_Click()
dlgChoose.Show
End Sub
Private Sub mnuDisplayVisual_Click()
Call GLmain
End Sub
Private Sub mnuDisplayCompare_Click()
MsgBox "Not Implemented", vbInformation, "Information"
End Sub
Private Sub mnuFileClose_Click()
Unload frmImport
If dataOpen = True Then
conDB.Close
End If
End
End Sub
Private Sub FileImport(NoRecords)
Dim i As Integer
Dim j As Integer
Dim X As Integer
Dim Y As Integer
'Dim neighbourA(1 To 2500) As Integer
'Dim neighboutB(1 To 2500) As Integer
Dim minA As Double
Dim minB As Double
Dim dist As Double
Let Y = 0
'redim the container arrays for northing easting masl and sdate
'Note there will be some empty records if errors occur
'ReDim sDate(1 To NoRecords)
ReDim Easting(1 To NoRecords)
ReDim Northing(1 To NoRecords)
ReDim masl(1 To NoRecords)
frmProgress.ProgressBar1.Min = 0
frmProgress.ProgressBar1.Max = RecordCounter
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Min
frmProgress.ProgressBar1.Visible = True
frmProgress.Show
frmProgress.txtName.Text = "Importing Geocoordinates"
frmImport.Enabled = False
For X = 1 To RecordCounter
'this loop tests the points values are valid and adds valid ones to an array
'test easting northing and masl are numeric values
If IsNumeric(ReadFile(X, 2)) Then
If IsNumeric(ReadFile(X, 3)) Then
If IsNumeric(ReadFile(X, 4)) Then
Y = Y + 1
' the date is not significant so I have removed its import
'If IsDate(ReadFile(x, 1)) Then
' Let sDate(y) = CDate(tDate)
'Else
' Let sDate(y) = Date
'End If
Let Northing(Y) = CSng(ReadFile(X, 3))
Let Easting(Y) = CSng(ReadFile(X, 2))
Let masl(Y) = CSng(ReadFile(X, 4))
End If
End If
End If
frmProgress.ProgressBar1.Value = X
Next X
frmProgress.ProgressBar1.Min = 1
frmProgress.ProgressBar1.Max = RecordCounter - 2
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Min
frmProgress.ProgressBar1.Visible = True
frmProgress.Show
'frmProgress.txtName.Text = "Calculating Triangles"
frmProgress.Refresh
Let RecordCounter = Y
'y records the actual number of units held in the array
'For i = 1 To RecordCounter - 2
'Assign a massive value to the containers for the minimum values
' minA = 10000000
' minB = 10000000
' For j = i + 1 To RecordCounter
' dist = Sqr((Easting(i) - Easting(j)) ^ 2 + (Northing(i) - Northing(j)) ^ 2 + (masl(i) - masl(j)) ^ 2)
' If dist < minA Then
' Let minA = dist
' ElseIf dist < minB Then
' Let minB = dist
'
' End If
' Next j
'MsgBox minA & " " & minB
' frmProgress.ProgressBar1.Value = i
'Next i
If RecordCounter > 0 Then
dataImport = True
End If
frmProgress.Hide
frmImport.Enabled = True
frmImport.Refresh
frmImport.SetFocus
End Sub
Private Sub OpenFile(fileopen, counter)
'Dim counter As Integer
Dim filename As String
Dim biffer As String
Dim i As Integer
'Reset filename
cdgImport.filename = ""
'display a common dialog box to open a csv file
cdgImport.Filter = "Comma seprated data | *.csv"
cdgImport.ShowOpen
filename = cdgImport.filename
'Counter is equal to zero so that it never exceeds the size of the array
If Len(filename) > 0 Then
'test if a file selected before attepting to open
Let counter = 0
Let fileopen = True
Open filename For Input As #1
'count records in a file
Do While Not EOF(1)
Let counter = counter + 1
Line Input #1, Buffer
Loop
ReDim ReadFile(1 To counter, 1 To 4)
'close and reopen file until I find a better way to get back to the begining of it
Close #1
Open filename For Input As #1
For i = 1 To counter
'Know how many record in the file so read them all in
Input #1, ReadFile(i, 1), ReadFile(i, 2), ReadFile(i, 3), ReadFile(i, 4)
Next i
Close #1
Let RecordCounter = counter
End If
End Sub
Private Sub mnuFileOpen_Click()
Dim fileopen As Boolean
Dim NoRecord As Integer
Let fileopen = False
Let NoRecord = 0
Call OpenFile(fileopen, NoRecords)
If fileopen = True Then
Call FileImport(NoRecords)
End If
End Sub
Private Sub Form_Load()
Set mod_name = dlgUpdate
cboSurveys.Clear
Call Read_Survey(mod_name)
End Sub
Private Sub OKButton_Click()
Call add_survey
End Sub
Private Sub add_survey()
'Procedure to add imported records to the database
Dim dataCommand As String ' used to build up the dataabase connection string
Dim i As Integer
dlgUpdate.Enabled = False
frmProgress.ProgressBar1.Min = 1
frmProgress.ProgressBar1.Max = RecordCounter
frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Min
frmProgress.txtName.Text = "Updating Database"
frmProgress.Show
frmProgress.Refresh
For i = 1 To RecordCounter
dataCommand = "INSERT INTO POINTS (NORTHING, EASTING, MASL, STUDYID) VALUES (" _
& Str(Northing(i)) & ", " & Str(Easting(i)) & ", " & Str(masl(i)) & ", " & Str(Current_Survey) & ");"
conDB.Execute (dataCommand)
frmProgress.ProgressBar1.Value = i
Next i
frmProgress.Hide
dlgUpdate.Enabled = True
dlgUpdate.Hide
frmImport.SetFocus
End Sub
[1] Theakstone WH, Jacobsen, FM (1997)
[2] Theakstone, WH et al (1999)
[3] Longley PA, et al (2001)
[4] Ashford and Odam 1998
[5] Jeff Melofee (2003)
[6] Bielig-Schulz, G and Schultz, CH (1990)
[7] Angel, E (2002)
[8] Deitel HM, Deitel, PJ (2002)
[9] Kernighan, BW and Richie, DM (1988)
[10] Theakstone 1997 and 1999.
[11] Melofee 2003 – http://nehe.gamedev.net
[12] MASL is short for Metres Above Sea Level
[13] Source www.whatis.com
[14] Pressman Page 42