' Paul B. Anderson's collection of ' Cylindrical map projection formulas ' in Visual Basic syntax ' Date: 02/07/2000 ' ' e-mail: pbander@yahoo.com ' or: pbander@series2000.com ' or: pbander@picusnet.com ' ' Constructive comments, corrections, ' and enhancements appreciated. ' ' ================================ ' Function used by some of the Map ' projection subroutines. ' ================================ Static Function LN#(n#) ' Dim Title As String Dim Msg As String Dim DgDef Dim Response ' If n# > 0# Then LN# = Log(n#) Else Title = "Function LN Error" ' Msg = " Input Number <= 0 " Msg = Msg + Chr$(10) + Chr$(10) Msg = Msg + " Program will End! " ' DgDef = 0 + 16 + 0 Response = MsgBox(Msg, DgDef, Title) ' END End If ' End Function ' { LN#. } ' ' ====================================================== ' The function below is used compute the correct Lambda ' value prior to calling the map projection subroutine. ' Both LambdaVal# and Lambda0Val# must be in Radians. ' ====================================================== Static Function Normalize#(LambdaVal#, Lambda0Val#) ' ' This subroutine is responsible for placing the Longitude (Lambda) ' value into the correct part of the map in relation to the selected ' Central Longitude (Lambda0) of the map. ' ' Local Variables Used ' -------------------- Dim LambdaDiff As Double ' Stores the difference between ' the current Lambda Value and ' the central Longitude. ' -------------------- ' LambdaDiff = LambdaVal# - Lambda0Val# ' Do While Abs(LambdaDiff) > PI If LambdaDiff < 0 Then LambdaDiff = LambdaDiff + (PI * 2) Else LambdaDiff = LambdaDiff - (PI * 2) End If Loop ' Normalize# = LambdaDiff ' End Function ' { Normalize#. } ' ' ========================== General Notes: ' ========================== ' 1> All formulas in this text file are for the Sphere ' 2> The # symbol indicates Double Precision, Floating Point ' 3> All standard parallels values (Phi0#) must be converted to Radians ' 4> An Example: In Basic 'Phi# ^ 3' means raise Phi# value to the 3rd power ' 5> SQR is Basic's Square Root function ' 6> PI - Global Constant - 3.1415926535898 ' 7> DEG2RAD - Global Constant - 1.74532925199433E-02 ' PI / 180 ' 8> RAD2DEG - Global Constant - 57.2957795130822 ' 180 / PI ' Some of the unreferenced formulas (will fix soon) contained ' here are from: ' 1) "An Album of Map Projections" ' - by Snyder & Voxland, 1987 & 1994 ' - U.S. Geological Survey Professional Paper 1453 ' ' 2) "Flattening the Earth: two thousand years of map projections" ' - by Snyder, 1993 & 1997 ' ' 3) "Coordinate Systems and Map Projections" ' - by Maling, 1992 ' ' 4) Dr. Waldo Tobler's published work ' ' 5) Snyder's personal software ' ' 6) Voxland's 'World' program documentation ' ' ====================================== ' Cylindrical map projection subroutines ' ====================================== ' Static Sub ArdenCloseCyl(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Arden-Close Cylindrical (1947) ' ' Note: ' Brief description in "Geographical By-ways and some other Geographical Essays" ' - by Col. Sir Charles Arden-Close ' Dim LocalPhi0# Dim MillerConst# Dim XOut1# Dim XOut2# Dim YOut1# Dim YOut2# ' ' Mercator Projection MillerConst# = 1# LocalPhi0# = 0 ' XOut1# = Radius# * Lambda# YOut1# = Radius# * MillerConst# * LN#(TAN(PI / 4# + Phi# / (2# * MillerConst#))) ' ' Lambert's Cylindrical Equal-Area Projection XOut2# = Radius# * Lambda# * COS(LocalPhi0#) YOut2# = Radius# * (1# / COS(LocalPhi0#)) * SIN(Phi#) ' XCoord# = (XOut1# + XOut2#) / 2# YCoord# = (YOut1# + YOut2#) / 2# ' End Sub ' { ArdenCloseCyl. } ' ' ========================= ' Static Sub Braun2(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Braun's Second (or Braun's Perspective) Cylindrical projection (1867) ' ' Note: ' Formulas from "Flattening the Earth: two thousand years of map projections" ' - by Snyder, 1993 & 1997 ' XCoord# = Radius# * Lambda# YCoord# = Radius# * (1.4# * SIN(Phi#) / (0.4# + COS(Phi#))) ' End Sub ' { Braun2. } ' ' =================== ' Static Sub CentralCyl(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Central (or Perspective) Cylindrical projection ' ' Notes: ' - Both inventer and creation date lost to history ' - Useful only as comparison to Mercator ' - Transverse aspect developed by Wetch ' ' Formulas from "An Album of Map Projections" by Snyder & Voxland, 1987 ' U.S. Geological Survey Professional Paper 1453 ' XCoord# = Radius# * Lambda# YCoord# = Radius# * TAN(Phi#) ' End Sub ' { CentralCyl. } ' ' ========================= ' Static Sub CylEqualArea(Radius#, Lambda#, Phi#, Phi0#, XCoord#, YCoord#) ' Cylindrical Equal-Area Projection ' ' - Standard Parallels (Phi0#) - convert to radians ' ----- ' 1) Phi0# = 0 Deg N&S (Tangent) ' Lambert's Cylindrical Equal-area projection (1772) ' Inventor ' ----- ' 2) Phi0# = 30 Deg N&S (Secant) ' Behrmann's projection (1910) ' Least mean maximum angular distortion for entire map ' ----- ' 3) Phi0# = 37.06667 Deg N&S (Secant) ' Limiting case of Hyperbolic Equal-area (Craster) ' ----- ' 4) Phi0# = 37.4 Deg N&S (Secant) ' Trystan Edwards, math corrected by Snyder ' ----- ' a) Phi0# = 50.8667 Deg N&S (Secant) ' Trystan Edwards original value, 1953 (Snyder)** ' ----- ' b) Phi0# = 37.38333 Deg N&S (Secant) ' Trystan Edwards projection, (Maling)** ' ----- ' 5) Phi0# = 45 Deg N&S (Secant) ' Gall's Orthographic/peters projection (Snyder & Maling) ' ----- ' a) Phi0# = 44.138 Deg N&S (Secant) ' peters projection (Voxland) ' ----- ' b) Phi0# = 46.03333 Deg N&S (Secant) ' Original error by Peters (Maling)** ' ----- ' 6) Phi0# = 55 Deg N&S (Secant) ' M. Balthasart's projection (Snyder) ' 1935 ' ----- ' a) Phi0# = 50 Deg N&S (Secant) ' M. Balthasart's projection (Maling) ' ----- ' ** No longer Equal-area ' ' Notes: ' - Lambert developed its transverse aspect (1772) ' - Behrmann also published in transverse & oblique aspects (1926) ' ' Formulas from "The World in Perspective" by Canters and Decleir, 1989 ' Published by John Wiley and Sons ' XCoord# = Radius# * Lambda# * COS(Phi0#) YCoord# = Radius# * (1# / COS(Phi0#)) * SIN(Phi#) ' End Sub ' { CylEqualArea. } ' ' ======================== ' Static Sub Equidistant(Radius#, Lambda#, Phi#, Phi0#, XCoord#, YCoord#) ' Cylindrical Equidistant (or Equirectangular, or Equi-rectangular) projection ' ' - Standard Parallels (Phi0#) - convert to radians ' ----- ' 1) Phi0# = 0 Deg N&S (Tangent) ' Plate Carrée ' Other names: a) Plane Chart ' b) Simple Cylindrical projection ' c) Geographic ' d) Unprojected ' ----- ' 2) Phi0# = 37.5 Deg N&S (Secant) ' Ronald Miller - Minimum overall scale distortion ' ----- ' 3) Phi0# = 42 Deg N&S (Secant) ' E. Grafarend and A. Niermann ' Minimum 'linear distortion' using Airy-Kavrayskiy criteria ' ----- ' 4) Phi0# = 43 Deg N&S (Secant) ' Ronald Miller - Minimum continental scale distortion ' ----- ' 5) Phi0# = 45 Deg N&S (Secant) ' Gall Isographic ' ----- ' 6) Phi0# = 50.5 Deg N&S (Secant) ' Ronald Miller's Equi-rectangular projection ' ----- ' 7) Phi0# = 61.7 Deg N&S (Secant) ' E. Grafarend and A. Niermann ' Minimum 'linear distortion' using Airy criteria ' ----- ' ' Notes: ' Transverse aspect of Plate Carrée developed by Cassini ' ' Formulas from "The World in Perspective" by Canters and Decleir, 1989 ' Published by John Wiley and Sons ' XCoord# = Radius# * Lambda# * COS(Phi0#) YCoord# = Radius# * Phi# ' End Sub ' { Equidistant. } ' ' ========================= ' Static Sub CylStereographic(Radius#, Lambda#, Phi#, Phi0#, XCoord#, YCoord#) ' Cylindrical Stereographic projection ' ' Note: ' This is a type of 'Perspective Cylindrical' ' ' - Standard Parallels (Phi0#) - convert to radians ' ----- ' 1) Phi0# = 0 Deg N&S (Tangent) ' Braun's Cylindrical Stereographic projection ' ----- ' 2) Phi0# = 30 Deg N&S (Secant) ' Bol'shoy sovetskiy atlas mira (BSAM) projection ' or Kamenetskiy's 2nd projection ' ----- ' 3) Phi0# = 45 Deg N&S (Secant) ' Gall's (Stereographic) projection ' Originator ' ----- ' 4) Phi0# = 55 Deg N&S (Secant) ' Kamenetskiy's 1st projection ' ----- ' 5) Phi0# = 66.1594674 Deg N&S (Secant) ' (O. M. Miller's) Modified Gall (Stereographic) projection ' - Use 'Phi0# = (2# / SQR(3#))' for this variation to get ' - the correct math precision for your software; don't ' - convert it to radians - it's already in the proper form! ' ----- ' ' Note: ' Formulas from "The World in Perspective" by Canters and Decleir, 1989 ' Published by John Wiley and Sons ' XCoord# = Radius# * Lambda# * COS(Phi0#) YCoord# = Radius# * (1# + COS(Phi0#)) * TAN(Phi# / 2#) ' End Sub ' { CylStereographic. } ' ' ============================ ' Static Sub KharchenkoShab(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Kharchenko-Shabanova Cylindrical projection ' XCoord# = Radius# * Lambda# * COS(10# * DEG2RAD) YCoord# = Radius# * (0.99 * Phi# + (0.0026263 * Phi# ^ 3) + (0.10734 * Phi# ^ 5)) ' End Sub ' { KharchenkoShab. } ' ' ========================== ' Static Sub Mercator(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Cylindrical Conformal projection, or Mercator (1569) ' ' Notes: ' Transverse aspect of Mercator developed by J. H. Lambert (1772) ' Oblique aspect of Mercator developed by Charles Sanders Peirce (1894) ' ' Formulas from "The World in Perspective" by Canters and Decleir, 1989 ' Published by John Wiley and Sons ' Dim MaxLat# Dim NotVisible ' NotVisible = 9999 MaxLat# <90 Deg ' If ABS(Phi# * RAD2DEG) <= MaxLat# Then XCoord# = Radius# * Lambda# YCoord# = Radius# * LN#(TAN(PI / 4 + Phi# / 2#)) Else XCoord# = NotVisible ' Out of range numeric value to force a NO PLOT End If ' End Sub ' { Mercator. } ' ' ======================== ' Static Sub Miller1(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' (O. M.) Miller (Cylindrical) Projection ' Other Names: ' - Miller 1 projection ' - Modified Mercator (b) ' XCoord# = Radius# * Lambda# ' ' Snyder version: YCoord# = (Radius# / .8#) * LN#(TAN((PI / 4#) + ((.8# * Phi#) / 2# ))) ' ' Canters and Decleir version: YCoord# = Radius# * 1.25# * LN#(TAN((PI / 4#) + (Phi# / (2# * 1.25#)))) ' End Sub ' { Miller1. } ' ' ==================== ' Static Sub Miller2(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' (O. M.) Miller 2 projection, or Modified Mercator (a) ' XCoord# = Radius# * Lambda# YCoord# = Radius# * 1.5# * LN#(TAN((PI/4) + (Phi# / 3#))) ' End Sub ' { Miller2. } ' ' ==================== ' Static Sub Pavlov(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Pavlov's (Cylindrical) projection ' ' Note: ' Formulas from "The World in Perspective" by Canters and Decleir, 1989 ' Published by John Wiley and Sons ' Dim A0# Dim A2# Dim A4# Dim Phi3# Dim Phi5# ' A0# = 1# A2# = -0.1531 A4# = -0.0267 Phi3# = Phi# ^ 3# Phi5# = Phi# ^ 5# ' XCoord# = Radius# * Lambda# YCoord# = Radius# * (A0# * Phi# + (A2# / 3#) * Phi3# + (A4# / 5#) * Phi5#) ' End Sub ' { Pavlov. } ' ' ================== ' Static Sub PerspectiveCompromise(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' (O. M. Miller's) Perspective Compromise ' XCoord# = Radius# * Lambda# YCoord# = Radius# * (SIN(Phi# / 2#) + TAN(Phi# / 2#)) ' ' ================================== ' Static Sub ToblerVar1(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Tobler's alternate #1 to (O. M.) Miller 1 Cylindrical projection ' XCoord# = Radius# * Lambda# YCoord# = Radius# * (Phi# + 1 / 6 * Phi# ^ 3) ' End Sub ' { ToblerVar1. } ' ' ====================== ' Static Sub ToblerVar2(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Tobler's alternate #2 to (O. M.) Miller 1 Cylindrical projection ' XCoord# = Radius# * Lambda# YCoord# = Radius# * (Phi# + 1 / 6 * Phi# ^ 3 + 1 / 24 * Phi# ^ 5) ' End Sub ' { ToblerVar2. } ' ' ===================== ' Static Sub ToblerWorldinSqr(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Tobler's World in a Square projection ' XCoord# = Radius# * (Lambda# / SQR(PI)) YCoord# = Radius# * SQR(PI) * SIN(Phi#) ' End Sub ' { ToblerWorldinSqr. } ' ' ============================ ' Static Sub Urmayev2(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Urmayev Cylindrical II projection ' ' Note: ' Formulas from John Parr Synder's personal software ' Dim P10# Dim P10SQ# ' P10# = Phi# / 10 / DEG2RAD P10SQ# = P10# * P10# ' XCoord# = Radius# * Lambda# YCoord# = Radius# * Phi# * (1 + P10SQ# * (188 / 48384 + P10SQ# / 80640)) ' End Sub ' { Urmayev2. } ' ' ==================== ' Static Sub Urmayev3(Radius#, Lambda#, Phi#, XCoord#, YCoord#) ' Urmayev Cylindrical III projection ' ' Note: ' Formulas from "The World in Perspective" by Canters and Decleir, 1989 ' Published by John Wiley and Sons ' Dim A0# Dim A2# Dim Phi3# ' A0# = 0.9281 A2# = 1.1143 Phi3# = Phi# ^ 3# ' XCoord# = Radius# * Lambda# YCoord# = Radius# * (A0# * Phi# + (A2# / 3#) * Phi3#) ' End Sub ' { Urmayev3. }