; ; FLEXPROJECTION (NATURAL EARTH PROJECTION) ; ========================================= ; ; Name: Flexprojection (Natural-Earth-Projektion) ; Quelle: Jenny, Bernhard, Zürich. Idee von Tom Patterson. ; Interactive design of small-scale map projections. ; Unpublished manuscript, B. Jenny, Zürich. ; Richtung: Direkt-Transformation ; ; Aus Robinson-Projektion, Originalvariante mit 5-Grad-Tabelle entwickelt. ; ; Die Natural Earth Projection wurde mit Hilfe des Jennyschen Flexprojection von Tom Patterson ; entwickelt. ; ; ! Flexprojector-Fixcode, der die Natural-Earth-Projektion erzeugt. ; ! Code immer vom Mastercode aus ändern! ; ; Das Grundprinzip des Flexprojektors ist Interpolation eines Kartennetzes anhand von ; tabellierten Koeffizienten. ; ; Es gibt 4 Tabellen: RX (Length of Parallels), RY (Distance of Parallels), ; RB (Bending) und RM (Meridians Distribution). RX, RY und RB sind Funktionen der ; geographische Bereite Phi, RM der geographische Länge Lambda. ; ; RX und RY stammen von Robinson, RB und RM hat Jenny hinzugefügt. ; ; Die Werte werden hier durch Fixcode fest derdrahtet eingestellt. ; ; Das Programm übernimmt die Koordinaten eines Punktes (x/y) und transformiert diese in einen Punkt (x'/y'). ; ; x/y sind ebene Zielpunktkoordinaten, x'/y' geben die geogr. Breite und Länge ; der Position auf der Quell-Erdkugel, auf der der Zielpunkt gelesen werden ; kann. ; Literatur: ; Jenny, B., Patterson, T., Hurni, L.: Interactive Design of Small-scale Map Projections. ; Unpublished manuskript. Zürich 2008. ; Evenden (2005) 5.2.31, S. 66. ; Eric M. Delmelle: Map Projection Properties. Considerations for Small-scale GIS Applications. ; GISaCC, Dept. of Geogr., Sept. 2001, S. 63. ; Jenny, B.; Patterson, T.: www.flexprojector.com (Zugriff 14.10.2008) ; Jenny, B.: Mail vom 17.10.2008 (Bending-Divisor 2) ; (C) Dr.-Ing. Rolf Böhm 2005, 2007, 2008 ; Benutzte Variablen ; ================== ; ; Hauptvariablen ; _name Flexprojection~(Natural~Earth~Projection) _var phi ; Geographische Breite _var lambda ; Geographische Länge _var lambda0 ; Geogr. Länge des Bildmittelpunktes _var scale ; Kartenmaßstabszahl (also 1000000, nicht 1/1000000) _var sign ; Vorzeichen ; ; Die 4 Koeffizienten ; _var rx ; Robinson-X-Koeffizient, bei Jenny l-phi ("Length") _var ry ; Robinson-Y-Koeffizient, bei Jenny d-phi ("Distance") _var rb ; Der 3. Koeffizient Jennys, "Bending", b-phi _var rm ; Der 4. Koeffizient Jennys "Meridians Distribution", m-lambda ; ; Zielvariablen des Flexprojector Interfaces ; ; Alle Variablen, die über die Flexprojector-Schnittstelle "hereinkommen" beginnen ; mit einem großen R wie Robinson ... ; _var Rs ; Jennys: Global Scale / s _var Rk ; Jenny: Proportions / k _dim RX 21 ; Length of Parallels (Robinsons X) _dim RY 21 ; Distance of Parallels form Equator (Robinsons Y) _dim RB 21 ; Bending _dim RM 15 ; Meridians Distribution ; ; Sonstige Variablen aus dem Jenny-Manuskript ; _var jskPi ; Jennys Factor s*k*Pi (= Robinsons Y-Factor) _var jBlp ; Jennys b-lambda-phi bei der Bending-Einrechnung; ; ; Interne Variablen der Unterprogramme ; _var .fix ; 1. Tafelwert _var .fix' ; 2. Tafelwert _var .fix'' ; 3. Tafelwert _var .frac ; Gebrochener Teil _var .frac- ; Gebrochener Teil minus 1 _var .v11 ; Untere Tafeldifferenz 1. Ordnung _var .v12 ; Obere Tafeldifferenz 1. Ordnung _var .v21 ; Tafeldifferenz 2. Ordnung ; ; Sonstiges ; _var oldphi ; Alte geographische Breite _var pi³ _var 15° _var return ; Globale Rücksprungadresse _var initial ; True: Progrmm ist initialisiert ; ; x, y, x', y', Cx', Cy', °(, (°, pi, pi/2 etc. sind vordefinierte globale Konstanten ; ; ; Initialisierung ; =============== ; tstne initial 077$ pause Hinweis:~Dieses~Programm~rechnet~eine~Vorwärtstransformation.\\Es~muss~mit~einer~direkt~arbeitenden~Projection~engine~abgearbeitet~werden. ; Konstanten berechnen mov pi³ pi mul pi³ pi mul pi³ pi mov 15° 15 mul 15° °( div 15° 2 ; JENNY: MAIL VOM 17.10. ; Zielvariablen des Flexprojektor Interface füllen mov return 053$ jump $$tab_fill 053$: ; Einige Konstanten berechnen mov jskPi Rk ; s mul jskPi Rs ; s*k mul jskPi pi ; s*k*pi ; Dialog input scale Maßstabszahl input lambda0 Mittelpunktslänge~in~Grad ; Eingegebene Werte auf Min/Max bringen clip scale 1 1E12 clip lambda0 -180 180 ; Programm ist initialisiert mov initial 1 077$: ; ; SIMD-Laufbereich ; ================ ; ; Eigentlicher Entwurf, dieser direkt! ; ------------------------------------ ; mov lambda x ; Geographische Länge mov phi y ; Geographische Breite sub lambda lambda0 cmpgt lambda -180 10$ add lambda 360 10$: cmpgt lambda -180 30$ add lambda 360 30$: cmplt lambda 180 40$ sub lambda 360 40$: cmplt lambda 180 50$ sub lambda 360 50$: ; x, y haben eine Zweifachbedeutung: ; - einmal die verdefinierten RTA-Input-Koordinaten, also eigentlich Phi und Lambda, ; - dann aber auch die ebenen Kartenkoordinaten, die errechnet werden, ; ; Umrechnung in Bogenmaß ; ---------------------- ; mul phi °( mul lambda °( mov sign phi sgn sign tstlt sign 89$ mov sign 1 ; Am Äquator muss sign 1 sein statt 0 89$: abs phi ; ; Flexprojector-Koeffizienten holen (In der Tabelle interpolieren) ; ---------------------------------------------------------------- ; cmpeq phi oldphi 91$ ; Nur wenn sich phi geändert hat: mov return 91$ jump $$tab_interpol_xyb ; X-Wert rx, Y-Wert ry und Bending-Wert rb an der Stelle phi holen 91$: mov oldphi phi mov return 93$ jump $$tab_interpol_m ; Immer: Meridian-Dist-Wert rm an der Stelle lambda holen 93$: ; ; Jennys b-lambda-phi jBlp berechnen ; ---------------------------------- ; mov r0 lambda sgn r0 mov r1 lambda mul r1 lambda mul r1 lambda abs r1 div r1 pi³ tstgt rb 96$ mov r0 1 sub r0 r1 mul r0 rb add r0 1 mov jBlp r0 jump 97$ 96$: mul r1 rb mov r0 1 sub r0 r1 mov jBlp r0 97$: ; ; Eigentlicher Entwurf ; -------------------- ; mov x lambda sgn x mul x rm ; Jenny: m-lambda mul x 15° ; jenny: d-m add x lambda ; (lambda + sgn(lambda)*rm*15°) mul x rx ; rx ... Jennys l-phi mul x Rs ; Jenny Global Scale / s / Robinsons X-Faktor 0.8487 mov y ry mul y jskPi ; Jannys s*k*Pi = Robinsons Y-Faktor 1.3523 mul y jBlp ; Bending: mit jBlp = Jennys b-lambda-phi multiplizieren mul y sign ; Nur y braucht noch das Vorzeichen von phi ; ; Maßstab, Kartenmittelpunkt etc. einrechnen ; ------------------------------------------ ; mul x Rx' ; Erdradius div x scale ; Kartenmaßstab add x Cx' ; mul y Ry' div y scale add y Cy' ; ; Schlussarbeiten ; --------------- ; 111$: mov x' x mov y' y exit ; ; Unterprogramm $$tab_interpol_xyb: Koeffizient aus Tabelle interpolieren ; ======================================================================= ; ; Die zu einer geographischen Breite phi zugehörigen Robinson-Jenny-Koeffizienten ; rx, ry und rb werden ermittelt. ; ; Definitionsbereich 0 ... 90 und noch etwas weiter. ; ; Die Parameter werden global übergeben. Das Unterprogramm erwartet: ; ; phi geographische Breite im Bogenmaß ; RX X-Tabelle als Feld mit den Elementen RX(0) ... RX(95) ; RY Y-Tabelle als Feld mit den Elementen RY(0) ... RY(95) ; RB B-(Bending)-Tabelle als Feld mit den Elementen RB(0) ... RB(95) ; return Rücksprungadresse ; ; Das Unterprogramm liefert: ; ; rx Robinson-Koeffizient x ; ry Robinson-Koeffizient Y ; rb Bending Koeffizient ; $$tab_interpol_xyb: ; ; phi in Vorkomma- und Nachkommateil zerlegen ; mov r1 phi mul r1 (° ; in Gradmaß div r1 5 ; in 5-Grad-Schritten clip r1 0 18 mov .fix r1 mov .frac r1 fix .fix ; erste Stützstelle mov .fix' .fix inc .fix' ; zweite Stützstelle mov .fix'' .fix' inc .fix'' ; dritte Stützstelle frac .frac ; Nachkommastellen mov .frac- .frac dec .frac- ; Um 1 verminderte Nachkommastellen ; ; X-Wert holen ; get r2 RX .fix ; Unterer Tafelwert get r3 RX .fix' ; Mittlerer Tafelwert get r4 RX .fix'' ; Oberer Tafelwert mov .v11 r3 ; 1. Tafeldifferenz 1. Ordnung berechnen sub .v11 r2 ; mov .v12 r4 ; 2. Tafeldifferenz 1. Ordnung berechnen sub .v12 r3 ; mov .v21 .v12 ; Tafeldifferenz 2. Ordnung berechnen sub .v21 .v11 ; mov rx r2 ; Tafelwert mul .v11 .frac ; 1. Tafeldifferenz * (.frac) add rx .v11 ; Verbesserung 1. Ordnung mul .v21 .frac ; 2. Tafeldifferenz * ((.frac)*(.frac-1)) / 2 mul .v21 .frac- div .v21 2 add rx .v21 ; Verbesserung 2. Ordnung ; ; Y-Wert holen ; get r2 RY .fix ; Unterer Tafelwert get r3 RY .fix' ; Mittlerer Tafelwert get r4 RY .fix'' ; Oberer Tafelwert mov .v11 r3 ; 1. Tafeldifferenz 1. Ordnung berechnen sub .v11 r2 ; mov .v12 r4 ; 2. Tafeldifferenz 1. Ordnung berechnen sub .v12 r3 ; mov .v21 .v12 ; Tafeldifferenz 2. Ordnung berechnen sub .v21 .v11 ; mov ry r2 ; Tafelwert mul .v11 .frac ; 1. Tafeldifferenz * (.frac) add ry .v11 ; Verbesserung 1. Ordnung mul .v21 .frac ; 2. Tafeldifferenz * ((.frac)*(.frac-1)) / 2 mul .v21 .frac- div .v21 2 add ry .v21 ; Verbesserung 2. Ordnung ; ; B-Wert holen: ; get r2 RB .fix ; Unterer Tafelwert get r3 RB .fix' ; Mittlerer Tafelwert get r4 RB .fix'' ; Oberer Tafelwert mov .v11 r3 ; 1. Tafeldifferenz 1. Ordnung berechnen sub .v11 r2 ; mov .v12 r4 ; 2. Tafeldifferenz 1. Ordnung berechnen sub .v12 r3 ; mov .v21 .v12 ; Tafeldifferenz 2. Ordnung berechnen sub .v21 .v11 ; mov rb r2 ; Tafelwert mul .v11 .frac ; 1. Tafeldifferenz * (.frac) add rb .v11 ; Verbesserung 1. Ordnung mul .v21 .frac ; 2. Tafeldifferenz * ((.frac)*(.frac-1)) / 2 mul .v21 .frac- div .v21 2 add rb .v21 ; Verbesserung 2. Ordnung ; ; Ende Unterprogramm tab_interpol_xyb ; jump return ; --------------------------------------------------------------------------------------------------------------- ; ; Unterprogramm $$tab_interpol_m: Meridian-Distribution Koeffizient aus Tabelle interpolieren ; =========================================================================================== ; ; Der zu einer geographischen Länge lambda zugehörigen Koeffizient rm wird berechnet. ; ; Definitionsbereich 0 ... 180 Gradund noch etwas weiter. ; ; Die Parameter werden global übergeben. Das Unterprogramm erwartet: ; ; phi geographische Breite im Bogenmaß ; RM Y-Tabelle als Feld mit den Elementen RM(0) ... RM(95) ; return Rücksprungadresse ; ; Das Unterprogramm liefert: ; ; rm Meridian-Distribution-Wert an der Stelle lambda ; $$tab_interpol_m: ; ; lambda in Vorkomma- und Nachkommateil zerlegen ; mov r1 lambda abs r1 mul r1 (° ; in Gradmaß div r1 15 ; in 15-Grad-Schritten clip r1 0 12 mov .fix r1 mov .frac r1 fix .fix ; erste Stützstelle mov .fix' .fix inc .fix' ; zweite Stützstelle mov .fix'' .fix' inc .fix'' ; dritte Stützstelle frac .frac ; Nachkommastellen mov .frac- .frac dec .frac- ; Um 1 verminderte Nachkommastellen ; ; M-Wert holen ; get r2 RM .fix ; Unterer Tafelwert get r3 RM .fix' ; Mittlerer Tafelwert get r4 RM .fix'' ; Oberer Tafelwert mov .v11 r3 ; 1. Tafeldifferenz 1. Ordnung berechnen sub .v11 r2 ; mov .v12 r4 ; 2. Tafeldifferenz 1. Ordnung berechnen sub .v12 r3 ; mov .v21 .v12 ; Tafeldifferenz 2. Ordnung berechnen sub .v21 .v11 ; mov rm r2 ; Tafelwert mul .v11 .frac ; 1. Tafeldifferenz * (.frac) add rm .v11 ; Verbesserung 1. Ordnung mul .v21 .frac ; 2. Tafeldifferenz * ((.frac)*(.frac-1)) / 2 mul .v21 .frac- div .v21 2 add rm .v21 ; Verbesserung 2. Ordnung ; ; Ende Unterprogramm tab_interpol_m ; jump return ; --------------------------------------------------------------------------------------------------------------- ; ; Unterprogramm $$tab_read: Tabelle mit Flexprojektor-Koeffizienten lesen ; ======================================================================= ; ; Das Unterprogramm liest die Datei "flexi.dat" in das Feld flexi. ; ; Die Parameter werden global übergeben. Das Unterprogramm erwartet: ; ; "flexi.dat" eine Datei mit den Flexprojector-Daten im aktuellen Verzeichnis. ; flexi eine leeres Feld mit den Elementen flexi(0) ... flexi(90) ; return Rücksprungadresse ; $$tab_read: mode 0 ; Andere Modi führen bei unrichtigen Datei/Feldlängen zu einer Unterbrechung read flexi 90 ; Datei lesen adrof flexi flexi(0) ; Feldpointer einstellen jump return ; --------------------------------------------------------------------------------------------------------------- ; ; Unterprogramm $$tab_fill: Projektion parametrieren ; ================================================== ; ; Es werden vier Tabellen mit festen Flexprojector-Koeffizienten x, y, Bending und ; Meridian dist gefüllt, außerdem noch einige Konstanten (Rk, Rs) - sog. Fixcode. ; $$tab_fill: ; ; Fixcode des Fixcoderecorders - Natural Earth Projection ; ; ** - mit Newtonsch interpolierenden aufsteigenden Differenzen 2. Ordnung manuell ergänzt. ; mov Rk 0.520000 mov Rs 0.870700 ; mov RX(0) 1.000000 mov RX(1) 0.998800 mov RX(2) 0.995300 mov RX(3) 0.989400 mov RX(4) 0.981100 mov RX(5) 0.970300 mov RX(6) 0.957000 mov RX(7) 0.940900 mov RX(8) 0.922200 mov RX(9) 0.900600 mov RX(10) 0.876300 mov RX(11) 0.849200 mov RX(12) 0.819600 mov RX(13) 0.787400 mov RX(14) 0.752500 mov RX(15) 0.716000 mov RX(16) 0.675400 mov RX(17) 0.627000 mov RX(18) 0.563000 mov RX(19) 0.483400 ; ** mov RX(20) 0.388200 ; ** ; mov RY(0) 0.000000 mov RY(1) 0.062000 mov RY(2) 0.124000 mov RY(3) 0.186000 mov RY(4) 0.248000 mov RY(5) 0.310000 mov RY(6) 0.372000 mov RY(7) 0.434000 mov RY(8) 0.495800 mov RY(9) 0.557100 mov RY(10) 0.617600 mov RY(11) 0.676900 mov RY(12) 0.734600 mov RY(13) 0.790300 mov RY(14) 0.843500 mov RY(15) 0.893600 mov RY(16) 0.939400 mov RY(17) 0.976100 mov RY(18) 1.000000 mov RY(19) 1.011100 ; ** mov RY(20) 1.009400 ; ** ; mov RB(0) 0.000000 mov RB(1) 0.000000 mov RB(2) 0.000000 mov RB(3) 0.000000 mov RB(4) 0.000000 mov RB(5) 0.000000 mov RB(6) 0.000000 mov RB(7) 0.000000 mov RB(8) 0.000000 mov RB(9) 0.000000 mov RB(10) 0.000000 mov RB(11) 0.000000 mov RB(12) 0.000000 mov RB(13) 0.000000 mov RB(14) 0.000000 mov RB(15) 0.000000 mov RB(16) 0.000000 mov RB(17) 0.000000 mov RB(18) 0.000000 mov RB(19) 0 ; ** mov RB(20) 0 ; ** ; mov RM(0) 0.000000 mov RM(1) 0.000000 mov RM(2) 0.000000 mov RM(3) 0.000000 mov RM(4) 0.000000 mov RM(5) 0.000000 mov RM(6) 0.000000 mov RM(7) 0.000000 mov RM(8) 0.000000 mov RM(9) 0.000000 mov RM(10) 0.000000 mov RM(11) 0.000000 mov RM(12) 0.000000 mov RM(19) 0 ; ** mov RM(20) 0 ; ** ; ; Ende Fixcode ; jump return _end