Degree BSc Computation and Geography


Student RN 99004279


Project Supervisor Dr. Roger Braithwaite


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

1. Introduction


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.1 Structure of the report


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.

1.2 Background

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.

1.3 Project Aims

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. 

1.4 Review of Relevant Literature

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.

1.5 Deliverables

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.

1.6 Overview of the project

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.

1.7 Educational value

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.

1.8 Technical challenge

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.

2. Requirements

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.

2.1 Functional requirements of the system

Read in data sets

The system must be able to read in the given data sets.

Transform 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.

2.2 Non Functional Requirements

Ease of use

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.

3. State of the Art

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.

3.1 Existing Systems

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. 

CAD packages

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.

GIS systems

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

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.





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

3. 2 Choice of visualisation method

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.

4. Design

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.

4.1 Approaches and Notation

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.

4.2 Conceptual Level Design

Figure 2 Use Case Diagram

Figure 3 Database Design

Figure 4 System Design

4.3 Communication of the design

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







Table 2 Fields in the Survey Table



Table 3 Fields in the Neighbours table


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

5. Implementation

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.

5.1 System Walkthrough

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

The visualisation display can be controlled using the following keys


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

5.2 Examination of Important Routines

Data Import

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).

Production of a Height map


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:


  1. Read the data and find the maximum and minimum values of the Easting, Northing and MASL.
  2. Calculate the ranges of Easting, Northing and MASL.
  3. Divide the ranges of Easting (x) and Northing (y) into 1024 equal steps and construct a grid in the (x, y) plane, consisting of 1024 by 1024 cells.
    i.e. (E, N) – from grid(0, 0) to grid(1023, 1023)
  4. Read the data again and map each point to the appropriate cell in the grid, storing the height (MASL) value in the appropriate cell. If a cell is occupied already, calculate the average height and store the value.



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

Database Implementation

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.

Changes to Time Plan

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.


5.3 Switch to Visual Basic

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.


6. Evaluation / Testing

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.

6.1 Testing the system

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.

File Handling

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.

Database operations

Data is checked for validity before being written to the database; incomplete records (missing Northing Easting or MASL) are rejected.

6.2 Testing Against the Requirements

The functional requirements of the system were: -

  1. Read in data sets
  2. Transform Data Sets
  3. Provide a visualisation of the GPS data sets.
  4. Calculations comparing the two datasets
  5. Ability to export data for use with GIS packages

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.

6.3 Evaluating the Approaches used

The evolutionary method proved to be a valid method of dealing with the project as it allowed for the system to change language used and to change the implementation to cope with the limitations of the data sets that were not apparent at the start. This method also allowed the various modules to be expanded in a controlled way as the complexities of the design became apparent.


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.

7. Conclusions and Further Work

7.1 Conclusions

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.

7.2 Further work

Apart from improving the quality of the visualisation the following problems could have been added.

Volume of Solid Displayed

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.

Comparing Two Figures

Comparisons of different data sets could be made as follows:

  1. Build a common grid (Easting by Northing) that accommodates both surveys.
  2. Find the least and greatest values of MASL shared between both surveys.
  3. Map the survey points from the first survey into the grid
  4. Map survey points from the second survey into the grid, subtracting the MASL value of the second survey from the MASL value of the first.
  5. Plot the difference.

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

8. Acknowledgements

Thanks to Roger Braithwaite for all his help, and to Andrew Conroy for all his programming tips, and advice.

9. Glossary of Terms

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.

10. References

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.

11. Table of Figures

Figure 1 Comparison table of methods 14

Figure 2 Use Case Diagram. 18

Figure 3 Database Design. 19

Figure 4 System Design. 19

Figure 5 Visualisation of the Survey Points 22

Figure 6 Graph Demonstrating the Sparse Spread of Survey Points 23

Figure 7 Screen Shot - Opening a file for import 25

Figure 8 Screen shot – A Common Dialog box used to open a database. 25

Figure 9 Screen Shot - Manage Survey Dialog. 26

Figure 10 Screen Shot - Add New Survey 26

Figure 11 Screen Shot - Adding the imported values to the survey database. 27

Figure 12 Screen Shot - Choose Data to Visualise. 27

Figure 13 Screen Shot of a Visualisation. 28

Figure 14 Screen Shot of a Visualisation Wire frame Mode. 29

Figure 15 - Graph of the 1995 Glacial Study using a 32 by 32 Grid. 30

Figure 16 Graph showing the interpolation methodology 32


Appendix A. Program Code

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.

Globals Module

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



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




   ReDim id(1 To SCounter)

   ReDim survey(1 To SCounter, 1 To 3)


   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))



   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)



      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"



  For i = 1 To RecordCounter

    Call setpoint(Easting(i), Northing(i), masl(i), minE, maxE, minN, maxN)

    frmProgress.ProgressBar1.Value = frmProgress.ProgressBar1.Value + 1


  Next i



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


   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


   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



  'East first

  For e = 0 To gridSize - 1

     count = countEast(e)

     If count > 1 Then

        Let STeps = 0

        Let iFrom = 0


           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


  Next e

  'next north

  For n = 0 To gridSize - 1

     count = countNorth(n)

     If count > 1 Then

        Let STeps = 0

        Let iFrom = 0


           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


  Next n


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


            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

OpenGL Routines

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


    Do While ShowCursor(True) <= -1         ' make sure the next call will show it


    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


    Do While ShowCursor(True) <= mPointerCount


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)


            ' 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.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



        Else                                    ' Not Time To Quit, Update Screen

            SwapBuffers (frm.hDC)               ' Swap Buffers (Double Buffering)


        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


    ' 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



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


        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



    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

Import Routines

Private Sub Form_Load()

  dataImport = False


End Sub

Private Sub mnuAboutInfo_Click()


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


     Call openData

  End If


End Sub

Private Sub openData()

  cdgImport.filename = ""

  cdgImport.Filter = "Microsoft Access Databases  |*.mdb"


  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


    End With

    dataOpen = True

  End If

End Sub


Private Sub mnuDatabaseSurvey_Click()

If dataOpen = True Then


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


     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()



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


  End If



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.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)



             '  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.txtName.Text = "Calculating Triangles"


   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


   frmImport.Enabled = True



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"


  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


     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

Update Database

Private Sub Form_Load()

   Set mod_name = dlgUpdate



   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"




  For i = 1 To RecordCounter


                    & Str(Northing(i)) & ", " & Str(Easting(i)) & ", " & Str(masl(i)) & ", " & Str(Current_Survey) & ");"


     conDB.Execute (dataCommand)

     frmProgress.ProgressBar1.Value = i

  Next i


  dlgUpdate.Enabled = True



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