proj.4

PROJ (many versions ago it was called PROJ.4) is a cartographic projections library written in C, originally written by Gerald Evenden (at that time at the USGS). It is in active use by quite a lot of applications, like QGIS [L1 ], GRASS GIS [L2 ], MapServer, PostGIS, and many others.

More information can be found here: http://proj.org/index.html (current version as of 2021-12-14 is version 8.2.0)

PROJ is released under an X/MIT license and thus can be used quite freely.

Tcl binding for PROJ

++++++++++++++++++++++

Note from 2021-12-14:

The following code still runs with the outdated proj.4 version 4.7.0

I am working on doing a new version now with the current PROJ version 8.2.0 and will then update this page and the links etc. pp (the links for the old version have already been updated)

++++++++++++++++++++++

TR (2010-06-10) It turned out, that making a Tcl binding to proj.4 was quite simple. It just took a few days to get all things right. There is a more or less well-defined API [L3 ], that can be used and what I am currently coming up with is a new Tcl package with the main command proj::project. It works like this:

package require tclproj
# give an input coordinate system in proj.4 format,
# an output coordinate system,
# and a list of x/y coordinate pairs in a list:
proj::project "+proj=latlong +ellps=clrk66" "+proj=merc +ellps=clrk66 +lat_ts=33" {-16 20.25}
-1495284.21147 1920596.78992

proj::project "+proj=latlong +ellps=WGS84" "+proj=merc +ellps=WGS84 +lat_ts=33" {-16 20.25 10.33 54.55 9.23433 55.01132}
-1495251.43594 1920692.42348 965371.708328 6078165.01069 862977.824527 6152753.87339

(2010-06-11) Today I added the proj::info command. It gives you the following:

# return the proj.4 release used here:
proj::info version
# return a list with the available projection identifiers and names:
proj::info projections
# return a list with the available ellipsoid identifiers and names:
proj::info ellipsoids
# return a list with the available datum identifiers and names:
proj::info datums
# return a list with the available conversion unit identifiers and names:
proj::info units

(2010-06-16) I have started to add some extra options to proj::project. The syntax is now:

 proj::project <origin> <target> <coords> ?option value ...?

where options can be:

optionvalue
-formata format string similar to the Tcl format command to allow for formatted output like 54°23'56.885"N
-scana similar format string allowing for formatted input instead on decimal degrees
-swappedcan be 'none', 'input', 'output', or 'both' allowing for switched x/y coordinate order in the coords list

The -format string accepts the following identifiers, assuming input as a decimal degree number:

identifiermeaning
%dthe integer part of the given number (degrees)
%mthe integer minutes part of the number
%sthe seconds part of the number
%Hthe hemisphere for an y coordinate, resulting in 'N' for North and 'S' for South
%Ethe "easting"/"meridian" for an x coordinate, resulting in 'E' for Eastern and 'W' for Western latitudes

This is not settled yet and the definitions are still not OK, but you get the idea where my goal is. Currently, I have no idea how to implement the -scan option. It would be nice, if The Tcl C API provided some kind of template for implementing your own scanning algorithms. I didn't use the C API Tcl_Format either, once to stay compatible to Tcl 8.4 and also because the identifiers don't fit in my case. My -format option is still very limited (no precision can be specified etc. ...)

Currently, only the -swapped option works 100%. The -format option works for simple cases like -format {%d°%m'%s''}.


Generally ...

As of now, there is basic error checking, and the commands project, info, and expand, but the heart is the proj::project command. The extension can be built with the proj.4 library statically linked in, so there is no need of seperately installing proj.4 on your system. My test system is a Mac right now, but my build script should also work nicely on Unix. I was also able to build it using mingw and MSYS on Windows.

It would be fairly easy to also add commands that correspond to the ones used in the tcllib module mapproj.


Download code and package

The current state of the package is here (containing the library and a pkgIndex.tcl script, no separate installation of proj.4 needed). The package should work with Tcl 8.4, 8.5, and 8.6.

  • tclproj-linux.zip [L4 ]
  • tclproj-mac.zip [L5 ], (for a x86_64 tclsh)
  • tclproj-win.zip [L6 ], using mingw and an appropriate def file
  • tclproj.c [L7 ], the current source code for the package (feel free to comment on this one)
  • make-tclproj.sh [L8 ], a bash shell script that I use for building the package
  • test-tclproj.tcl [L9 ], a tcltest script for the new commands

Discussion

arjen - 2010-06-11 03:06:59

Torsten, you have beaten me to it :). Nice work.

TR - Good to hear!


JHJL - 2010-06-15

Have just built on Windows XP using Visual Studio 2008 Pro. Only change was to add a DLLEXPORT Tclproj_init. Thanks for making this available.

TR - Can you tell me where exactly yo have put this line, then I can integrate it. Maybe you want to provide me with the dll also, then I can make it available here?

JHJL IRC it was int DLLEXPORT Tclproj_Init (... Unfortunately I cannot supply a DLL at present becasue it is on a standalone secure development machine which is not connected to the Internet. If I can find time I will try to recreate at home.

TR - Alright. I was now able to compile using mingw.

BTW Is there any chance of allowing the use of a "z" coordinate in your interface?

TR - Sure, this is quite easy. The only thing is, it interferes with the -swapped option. There is no straight forward way of specifying in what order the coordinates are, when there are x,y, and z. With x and y there are only 2 possibilities (xy and yx, reversed or not). With x,y,z there are 6: xyz, xzy, yxz, yzx, zxy, zyx. So I need to think of another way to do the -swapped option. Let me think about this for a little while, since I do not like to have complicated options that no-one can understand and use ...

TR - OK, how about defining this as options -dimensions which can have the value 2 (for x and y) or 3 (for x,y, and z) and two accompanying options -inputorder and -outputorder that can take the values xy,yx,xyz,xzy,yxz,yzx,zxy,zyx and defined the order of the given or returned coordinates. These options would replace the -swapped option. The default for '-dimensions 2' would be '-inputorder xy -outputorder xy' and the default for '-dimensions 3' would be '-inputorder xyz -outputorder xyz'. The default for -dimensions would be 2. Thus, the most used case of having x,y coordinates in the "normal" order would serve as the default. Does that sound sensible?


nb Torsten, any chance you can do this for the gdal and ogr libraries, if we ask nicely ;-)

TR This could be done, yes, but there is no real need. We have already tkimggdal and the The tcl-map GSoC2009 project which provides access to gdal. Or is there anything missing there, you would need?


Other related stuff and links

Since this project appears defunct, I've created an alternative proj4tcl

Related topics on the wiki: geodesy

The NAP package also has a binding to proj.4, but the usage is only within the nap command. See also: Analysing geographical data with NAP