[pd]: This a binding to the [https://trac.osgeo.org/proj/%|%proj4%|%] projection library. See [http://trac.osgeo.org/proj/wiki/ProjAPI#EXAMPLE%|% Proj API reference Example %|%] This implementation requires [http://andreas-kupries.github.io/critcl/%|%critcl%|%] <> proj4tcl.tcl ====== # proj4tcl.tcl # package require critcl 3.1 package require critcl::class critcl::tcl 8.5 critcl::clibraries -lproj critcl::ccode { #include } critcl::class::define proj4 { type projPJ constructor { if (objc != 1) { Tcl_WrongNumArgs (interp, objcskip, objv-objcskip, "initstring"); goto error; } char *defn = Tcl_GetString(objv[0]); instance = pj_init_plus(defn); if (instance == NULL) { Tcl_AppendResult(interp, "proj definition error: ", pj_strerrno(pj_errno), NULL); goto error; } } destructor { pj_free(instance); } method to proc { char* dest Tcl_Obj* point } ok { int n; double x,y,z; Tcl_Obj **d,*l; Tcl_CmdInfo destinfo; projPJ dest_cs; if (Tcl_GetCommandInfo(interp, dest, &destinfo) == 0) { Tcl_AppendResult(interp,"Command not found: ", dest, NULL); return TCL_ERROR; } dest_cs = (projPJ) destinfo.objClientData; if (Tcl_ListObjGetElements(interp, point, &n, &d) != TCL_OK) { return TCL_ERROR; } if (n != 3) { Tcl_AppendResult(interp,"not 3D point: ", NULL); return TCL_ERROR; } if (Tcl_GetDoubleFromObj(interp, d[0], &x) != TCL_OK || Tcl_GetDoubleFromObj(interp, d[1], &y) != TCL_OK || Tcl_GetDoubleFromObj(interp, d[2], &z) != TCL_OK) { return TCL_ERROR; } if (pj_is_latlong(instance)) { x *= DEG_TO_RAD; y *= DEG_TO_RAD; } if (pj_transform(instance,dest_cs,1,1,&x,&y,&z)) { Tcl_AppendResult(interp, "proj error: ", pj_strerrno(pj_errno), NULL); return TCL_ERROR; } if (pj_is_latlong(dest_cs)) { x *= RAD_TO_DEG; y *= RAD_TO_DEG; } l = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(x)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(y)); Tcl_ListObjAppendElement(interp, l, Tcl_NewDoubleObj(z)); Tcl_SetObjResult(interp, l); return TCL_OK; } } package provide proj4tcl 1 #end ====== <> **Compile** ====== critcl -pkg proj4tcl.tcl ====== **Use** ====== lappend auto_path [pwd]/lib package require proj4tcl # Create coordinate systems proj4 create mga56 "+proj=utm +zone=56 +south +ellps=GRS80 " proj4 create gda94 "+proj=latlon +axis=neu +ellps=GRS80" # A 3d point is just a 3-item list # order is defined by the proj.4 +axis option set pos [list 502810 6964520 0] # Convert the point set result [mga56 to gda94 $pos] puts [format "%.5f %.5f %.2f" {*}$result] # lats and lons are in decimal degrees. # output -> -27.44279 153.02843 0.00 ====== **Using Vertical Datums ** See [https://trac.osgeo.org/proj/wiki/VerticalDatums%|%Vertical Datums%|%] ====== set env(PROJ_LIB) [pwd] # need to make/get .gtx file proj4 create mga56ag09 "+proj=utm +zone=56 +south +ellps=GRS80 +geoidgrids=ausgeoid09.gtx" set result [mga56ag09 to gda94 $pos] puts [format "%.5f %.5f %.3f" {*}$result] # output -> -27.44279 153.02843 41.901 ====== **Windows** Place proj_api.h and libproj-0.dll in the same directory as proj4tcl.tcl.<
> libproj-0.dll becomes part of the package using the preload command. ====== package require critcl 3.1 package require critcl::class critcl::tcl 8.5 set dir [pwd] critcl::cheaders -I$dir critcl::include proj_api.h critcl::clibraries -L$dir critcl::clibraries $dir/libproj-0.dll critcl::preload $dir/libproj-0 ====== Compiling with mingw32 ====== critcl -target mingw32 -pkg proj4tcl ====== <>Geography | Critcl