Pascal Dynamic Libraries: More Than You Want To Know

Part 3: Pascal for GIS


Contents

Introduction
What's Included
Setting Up
Testing the GDAL unit
SwiftCast: Using a Pascal library and Bing Maps in a Swift app
AspCast: Using a Pascal library in a DotSpatial ASP.NET Web app
PyCast: Using a Pascal module with a Python plugin for QGIS
PasCast: Using a Pascal library with Lazarus GIS controls
QxCast: Using a Pascal library and OpenStreetMap in a qooxdoo Mobile Web app
BoxCast: Using a Pascal library and Mapbox GL in a Web app
Future topics and to-do list


Introduction

These notes describe the current status of the Pascal for GIS toolkit. They assume that you know something about GIS. If you're just starting out with GIS, you may find that browsing an online resource like this will be helpful:

GIS (geographic information system)

Pascal has never been relevant in the world of GIS; nor is that situation likely to change. Historically the primary language of GIS has been C++ for the low-level libraries and the GIS application itself, supplemented by Python for writing scripts that utilize the libraries and for developing plugins that extend the GIS app. In recent years, C# has emerged as a language for doing both the low- and high-level stuff with the same language.

Nevertheless, that doesn't mean you can't use Pascal with GIS. Here are a few examples of where Pascal might make sense:

Typically you would use Pascal for parts of these tasks to take advantage of existing Pascal code that you don't want to rewrite in one or more other languages. Note that if you put your Pascal code into a compiled library, you can use it with code written in virtually any language (C, C#, Python, even Swift), meaning you only have to write it once to use with multiple GIS tools.


What's Included

The Pascal for GIS toolkit includes units and example code for working with several of the GIS tools listed below. The examples range from do-it-yourself without mapping (testgdal), to a simple map with basic pan and zoom (SwiftCast and QxCast), to a clickable but read-only map (AspCast), to a clickable read-write map (PyCast and PasCast). The primary focus is Mac OS X, but several of the examples can be tested on Windows and Linux too. The Free Pascal compiler is assumed throughout, but Delphi can generally be used as well on Windows.

GIS library, app or service URL Description Version tested Pros Cons
GDAL www.gdal.org Geospatial Data Abstraction Library; reads and writes virtually any format raster or vector file. 1.11 Windows, OS X, Linux; well-documented; includes many useful command-line utilities; most open-source GISs include or depend on this library; X/MIT license. Might be a bit bulky to include with your own app; stable version is out-of-date with some Linux releases.
SAGA GIS sourceforge.net/projects/saga-gis Great number-crunching GIS with some highly specialized modules. Windows, OS X, Linux; script or shell to SAGA's command-line program to do just about anything the UI can do; uses its own raster file format that can be directly read and written by Pascal; includes GDAL; LGPL license for libraries. Includes clumsy desktop GIS based on wxWidgets; requires wxWidgets even for command-line program; poorly documented.
DotSpatial dotspatial.codeplex.com .NET assemblies for building a Windows.Forms-based desktop GIS or an ASP.NET Web app. 1.7 trunk Windows, OS X, Linux; full download includes GDAL binaries for Windows; has start of Cocoa map controls using MonoMac; LGPL license. Windows.Forms-based UI works best only on Windows; although 100% C#, some plugins depend on native libraries (eg, GDAL).
QGIS qgis.org Popular GIS that's great for ad hoc use. 2.8 Windows, OS X, Linux; easily extended with Python plugins; Qt-based GIS interface looks good on all platforms; includes Qt, GDAL, SAGA and, on Windows, Python. GPL license for libraries, meaning any QGIS plugin you write must also be GPL; enormous installation footprint; documentation not always up-to-date.
Map Kit framework References for OS X and iOS Apple's embeddable mapping interface for OS X and iOS. Provides same look and feel as Apple's Maps app; now a standard framework on both iOS and OS X; no longer depends on Google map services; well-documented. Only available on Apple platforms; requires enrollment in Mac Developer Program; not really a GIS per se.
Google Maps, Bing Maps, Apple Maps, OpenStreetMap https://www.google.com/maps
http://www.bing.com/maps
http://www.openstreetmap.org
Services for supplying aerial imagery and other GIS layers for Web pages and Internet-aware GIS apps. Bing 6.2,
OpenLayers 2.13
Can be used with any Web browser app or control; good way of eliminating need for local copies of aerial photos for a GIS; handy for simple mapping. Unless imagery cached, requires Internet connection; may be some restrictions on use in an app; not really a GIS per se.


Setting Up

  1. Free Pascal compiler

    Install the latest stable version.

    freepascal.org

  2. Pascal for GIS source code

    All example code mentioned in this article is available here: p4g.zip

    Change log is here: p4g-changelog.txt

    If you haven't already done so, you'll probably want to review Part 1 and Part 2 of the Pascal Dynamic Libraries articles, which explain the library-related code.

  3. GIS libraries and apps

    Install the GIS libraries and apps listed in the table above that you're interested in.

    Tip: If you install QGIS, you also get the GDAL library, the SAGA command-line program and libraries, and Python (the latter Windows-only; OS X and Linux already have Python installed).

  4. Sample data

    This toolkit does not include sample data except for what's included with the examples. If you need more, download the classic Spearfish dataset from here:

    grass.osgeo.org/download/sample-data

    Tip: Use this Web site to zoom in on any location in the USA and clip out and download GIS layers for up to 10,000 acres. Included in the downloaded zip file will be soil and watershed shapefiles (vector data) as well as an elevation data file, aerial photo and topographic map (raster data):

    clipper.missouri.edu/index.asp


Testing the GDAL unit

The GDAL library has a C interface, so you'll need to parse GDAL's header files (.h) before you can use GDAL with Pascal. Some of this has already been done for you and is included as the GDAL unit in the Pascal for GIS source.

Obtaining the GDAL library

To obtain the GDAL library on Windows, just install SAGA GIS, DotSpatial or QGIS as these all include GDAL. You can also download GDAL from here:

http://www.gisinternals.com

To obtain the GDAL library on OS X, there are two options:

  1. Download the "GDAL Complete" .dmg from here:

    http://www.kyngchaos.com/software/frameworks

    This .dmg installs GDAL and several other frameworks (PROJ, GEOS, etc.) into /Library/Frameworks. Note that these frameworks are required for QGIS on OS X and can also be used with SAGA GIS and DotSpatial on OS X. Note that the frameworks are all universal, meaning they can be used with both 32- and 64-bit apps.

  2. Build GDAL yourself.

    Build the PROJ library too (if you need to reproject spatial data).

Testing the GDAL library

To test the GDAL unit with the GDAL library, change to the directory where the GDAL unit source files and testgdal.pas are located. This simple console app can be used to display a few bits of information about virtually any vector or raster data file.

Note that depending on what version of the GDAL library you want to test, you may need to edit GDAL.pas and specify the library name to use with Windows if it's different from the default (gdal111.dll).

To test the app with the GDAL library on OS X, do one of the following:

  1. If you built and installed GDAL to /usr/local/lib as described above, you don't need to do anything.

  2. If you built GDAL above, but did not install it, copy libgdal.1.dylib to where testgdal.pas is located, then enter this:
      mv libgdal.1.dylib libgdal.dylib
      install_name_tool libgdal.dylib -id ./libgdal.dylib
    
  3. If you installed the GDAL framework and want to use it instead of the library, compile with the -dGDAL_FRAMEWORK switch to link against the GDAL framework instead of the library.
Now compile the testgdal app:
  ppc386 testgdal
Note that if you have only the 64-bit GDAL library, you'll need to compile testgdal.pas with ppcx64 (OS X) or ppcrossx64 (Windows).

On OS X, you can see what the executable is linked against as follows:

  otool -L testgdal
To test the app with the GDAL library on Windows, you'll need a path to the GDAL library. For example, to use QGIS's GDAL library with the test app, enter this in a batch file:

  setlocal
  set PATH=C:\Program Files (x86)\QGIS\bin;%PATH%
  testgdal %1%
Run the app and specify a vector or raster file to examine. Examples:

  On OS X:     ./testgdal someshapefile.shp
  On Windows:  testgdal.bat somegridfile.asc

Testing the GDAL and PROJ libraries

If the GDAL library can find the PROJ library, you can also use the GDAL transformation (projection) functions. The testshapes.pas console app is supplied for testing these functions.

On OS X, compile the testshapes app like this:

  ppc386 -Fu../ndfd testshapes
To use the GDAL and PROJ frameworks instead of the libraries, include the -dGDAL_FRAMEWORK switch.

On Windows, compile the testshapes app like this:

  ppc386 -Fu..\ndfd testshapes
When run, testshapes will create the locations shapefile used in the PasCast example below.


SwiftCast: Using a Pascal library and Bing Maps in a Swift app

SwiftCast is an example app for OS X that shows how to:

A screenshot of SwiftCast is here: SwiftCast.jpg

To try out SwiftCast, you have two options:

A screenshot of the SwiftCast project in Xcode is here: SwiftCast-Xcode.jpg

Notes on SwiftCast:

  1. SwiftCast loads file viewForecast.bing.6.2.html into its WebView control. This file's JavaScript code uses version 6.2 of Bing Maps. One drawback to version 6.2 is that it doesn't appear to have a way to label points on the map directly. Instead, you position the mouse over a location's pushpin and its label will pop up. Bing 7.0 has a way to label points directly, but 7.0 requires signing up for a developer account to use it. Google Maps could also be used. To use a different mapping service, just replace JavaScript functions showMap and showLocation, which look like this for Bing 6.2:
        function showMap(lat, lon) {
          map = new VEMap('map');
          map.LoadMap(new VELatLong(lat, lon), 10, VEMapStyle.Road, false);
        }
    
        function showLocation(lat, lon, location, forecast) {
          var point = new VELatLong(lat, lon);
          var pin = new VEShape(VEShapeType.Pushpin, point);
          pin.SetTitle(location);
          pin.SetDescription(forecast);
          map.AddShape(pin);
        }
  2. SwiftCast loads a local copy of an HTML file into its WebView control, looking for it in its Resources folder using this bit of code:
        let htmlPath = Bundle.main.resourcePath! + "/viewForecast.bing.6.2.html"
    But there's no reason why this file couldn't be loaded by specifying an https:// location. That would allow you to update the HTML that's loaded without needing to update the app itself.

  3. Several of the default menus that Xcode's template adds to a new app are not relevant to a simple app like SwiftCast. However, these menus have been left alone in case someone wants to extend SwiftCast, for example, to support loading a file containing locations and lat/lon coordinates rather than just using the app's hard-wired locations.
Adding the ndfd library to an Xcode Swift project is fairly straightforward:


AspCast: Using a Pascal library in a DotSpatial ASP.NET Web app

AspCast is an example app for .NET and Mono that shows how to:

A screenshot of AspCast is here: AspCast.jpg

To try out AspCast, you have several options. Be sure to copy the required DotSpatial assemblies, the ndfd native library and its interop assembly as described below.

A screenshot of the AspCast project in Xamarin Studio is here: AspCast-XamarinStudio.jpg

Notes on AspCast:

  1. ASP.NET apps sometimes get shut down immediately when run with Xamarin Studio's Mono Web server on Windows. If this happens, try running AspCast with a different Web server, such as IIS Express.

  2. AspCast works fairly well in Safari on an iPad too, with the exception of panning the map, which conflicts with normal scrolling within the browser.
Creating a DotSpatial ASP.NET app is fairly straightforward:


PyCast: Using a Pascal module with a Python plugin for QGIS

PyCast is an example plugin for QGIS that shows how to:

A screenshot of PyCast is here: PyCast.jpg

To try out the PyCast plugin, follow these steps to add it to QGIS:

A screenshot of a PyCast source file in TextWrangler is here: PyCast-TextWrangler.jpg

Notes on PyCast:

  1. Typically QGIS plugins are installed in a submenu under one of the standard program menus, so the PyCast plugin is installed under the Web menu along with the OpenLayers plugin.

  2. QGIS plugins are usually downloaded and installed automatically via the plugin manager, but since PyCast requires two binary files that you need to build, it isn't currently distributed that way.

  3. Sometimes OpenLayers maps don't fully download and a few tiles may be blank. You can usually remedy this by choosing View | Refresh or panning the map a little bit to force the tiles to be reloaded.
Creating a Python plugin for QGIS involves several tools. Since the Python source for all plugins is included, you might find it easier just to adapt an existing plugin or learn how to write a plugin by reviewing the code of PyCast or other plugins. However, you can also follow these steps to create a simple plugin that will be installed under the Plugins menu:

QGIS API documentation is here: http://www.qgis.org/en/docs/index.html


PasCast: Using a Pascal library with Lazarus GIS controls

PasCast is a cross-platform example app for Lazarus that shows how to:

A screenshot of PasCast is here: PasCast.jpg

To try out PasCast, you have two options:

A screenshot of the PasCast project in Lazarus is here: PasCast-Lazarus.jpg

Notes on PasCast:

  1. The downloadable PasCast.dmg's app bundle includes all of the layer files PasCast needs, as well as its own copies of the GDAL, PROJ and ndfd libraries, so you don't need to install anything else to run it.

  2. After compiling PasCast, Lazarus will attempt to run the fixlazbundle.sh script to fix up the PasCast.app bundle on OS X. This script is not needed on other platforms and will fail with an error message in the build log. You can ignore this message on other platforms.

  3. PasCast displays a map of an area of southwestern Colorado. While the area is not large geographically as weather forecasts go, it does have dramatic changes in elevation (>1000m). When you click around on the map to get a forecast, you would expect the forecast to change, but it mostly doesn't, suggesting that the NDFD forecast model does not fully account for local elevation differences.
Using the P4G_Ctrls GIS controls with Lazarus is fairly straightforward:

Lazarus documentation is here: http://www.lazarus-ide.org


QxCast: Using a Pascal library and OpenStreetMap in a qooxdoo Mobile Web app

QxCast is a mobile Web app that shows how to:

A screenshot of QxCast is here: QxCast.jpg

To try out QxCast locally, first set up the getforecast server app. The getforecast server app has no dependencies outside of Free Pascal and the ndfd library's Pascal wrapper class, so just compile it and copy getforecast.cgi and the ndfd library (previously compiled elsewhere) to the server app's folder With IIS, you also copy getforecast's web.config file.

On Mac, the server app files go under /Library/WebServer/CGI-Executables. On Windows, they go under C:\inetpub\wwwroot.

Now follow the steps for running the client app for the Unicodum demo app here.

A screenshot of the QxCast client project in Lazarus is here: QxCast-Lazarus.jpg

Notes on QxCast:

  1. See Part 4 for tips on deploying a CGI app on an actual server (not just locally).


BoxCast: Using a Pascal library and Mapbox GL in a Web app

BoxCast is a Web app that shows how to:

A screenshot of BoxCast is here: BoxCast.jpg

To try out BoxCast locally, first set up QxCast's getforecast server app (see notes above). Then open BoxCast's index.html file in a browser.

A screenshot of the boxcast.js client file is here: BoxCast-TextWrangler.jpg

Notes on BoxCast:

  1. See Part 4 for tips on deploying a CGI app on an actual server (not just locally).

  2. The qooxdoo framework used by QxCast above uses JSONP to work around browser restrictions on cross-domain calls. Mapbox uses a newer approach called CORS. With Apache, this requires a small change to its httpd.conf file (in /etc/apache2). With IIS, the web.config file deployed with getforecast.cgi takes care of enabling CORS for the server app.

  3. To deploy the BoxCast client files, copy and place index.html, boxcast.js and boxcast-config.js together. By default, boxcast-config.js assumes the server app will be running locally (http://localhost/cgi-bin/getforecast.cgi). Edit the URL in this config file to call the server app on a remote server.
Mapbox GL is a powerful Javascript mapping library, but it can also be used with Mapbox Studio, a Web-based tool for creating your own custom maps (called styles). In addition, you can create and use your own vector tilesets in Mapbox Studio by uploading zipped shapefiles and then associating the resulting tilesets with layers in your custom map. You can also host your own styles and tilesets on Mapbox and reference them in your Web apps.

You can try out Mapbox Studio for free by creating a Mapbox account.

Note that BoxCast uses a standard Mapbox style and does not use any tilesets outside of what the standard map style uses (roads, satellite imagery, etc.).


Future topics and to-do list

  1. Create iSwiftCast example for iPad?
  2. Investigate GIS options for iOS?

Copyright 2015 by Phil Hess.

macpgmr (at) icloud (dot) com

First posted March 19, 2015; last edited June 10, 2017.