I detta inlägg tänker jag använda javaskript för att göra ett ”enkelt” formulär som översätter koordinater från ett system till ett annat.
Jag skall försöka hålla koden så enkel och ”ren” som möjligt, så att det senare går att inkludera den i andra sammanhang så smidigt som möjligt.
Det skall dock gå att använda formuläret fristående, just för att översätta koordinater ”on the go”. Det skall därför inte krävas några webbservrar eller installationer. En webbläsare är allt som skall behövas, plus lite skriptfiler.
Formulär i HTML och javaskript är inget som är nytt, utan kan väl mer klassas som grundläggande programmeringskunskaper nu för tiden. Kan du ingen programmering, så är HTML och javaskript i mitt tycke det bästa sättet att börja då det i praktiken räcker med en webbläsare och möjlighet att redigera textfiler.
Jag skriver inte alla skript själv, utan tänker använda mig av Proj4JS som är en javaskriptversion av Proj4 biblioteket. Det går att ladda hem Proj4JS från GitHub (https://github.com/proj4js/proj4js/releases).
Har man tillgång till Internet hela tiden så kan man använda en referens till en on-line källa i stället för att ladda ned filerna (https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.14/proj4.js).
Proj4JS är en 74 kB stor fil med komprimerad javaskript, så den är lite svår att läsa, men det går om man vill. Det finns även filer med koden okomprimerad, som är betydligt lättare att läsa och fungerar lika bra att använda i formuläret.
Att använda Proj4JS är väldigt enkelt. Syntaxen är:
proj4(källprojektion[, målprojektion, koordinater])
Sedan skall detta paketeras i HTML så att det fungerar också.
Väldigt grundläggande HTML består i princip av koden till höger. En första rad som anger att det är kod enligt HTML5 standard. En start- och slut-tag för själva HTML koden. En start- och slut-tag för huvudet där mycket av referenser till annan kod och deklarationer kommer att skrivas. En start- och slut-tag för huvuddokumentet som styr innehållet på sidan.
För den enklaste formen av formulär behöver jag två fält för X och Y koordinater i källprojektionen och två fält för X och Y i målprojektionen.
Dessutom så behövs det någon form knapp för att starta omvandlingen.
Det går att skriva koden för ett formulär på massor av olika sätt, det som visas ovan är ren HTML och kanske inte så praktiskt när man skall använda funktioner i javaskript.
Jag ändrar koden för knappen till en ”<button>” tagg med ett ”on-click” event.
<button type=button onclick="transform(this.form)">Omvandla</button>
Sedan lägger jag till funktionen ”transform(form)” i huvud taggen, tillsammans med en referens till ”proj4.js”. Detta förutsätter att filen proj4.js finns på samma plats som HTML dokumentet.
Den kod som jag nu kommer att skriva i funktionen kommer att köras varje gång man trycker på knappen, och det går att hänvisa till ”form” och de namn som getts de olika formulärfälten på ett enkelt sätt.
Låt oss anta att omvandlingen alltid görs från WGS84 longitud och latitud i decimala grader till SWEREF99TM. Detta kan utvecklas senare till ett mera aktivt val.
function transform(form) { proj4.defs([ ['WGS84', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"], ['SWEREF99TM',"+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"] ]); var source='WGS84'; var target='SWEREF99TM'; var result = proj4(source, target, [form.sourceX.value, form.sourceY.value]); form.targetX.value = result[0]; form.targetY.value = result[1]; }
Funktionen inleds med att projektionerna definieras. När det gäller WGS84 så behövs det egentligen inte, men på det här sättet blir det lättare att läsa koden och att expandera den med fler projektioner framöver.
Här anger jag rakt upp och ned att det är WGS84 och SWEREF99TM som skall användas, men på sikt så skulle man kunna göra även detta valbart, kopplat till definierade projektioner.
Kommandot proj4 använder käll- och målprojektion tillsammans med innehållet i formulärfälten för käll-koordinaterna. Resultatet hamnar i en variabel som en lista.
Denna lista skrivs sedan till de båda mål-koordinatfälten.
Tada!
Nu kan man expandera koden, snygga till decimaler, anpassa beräkningarna till flera typer av projektioner, med mera.
Med enbart några få rader kod går det att göra väldigt användbara saker med HTML och javaskript.
Hela HTML koden:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <skript src="proj4.js"></skript> <skript language="JavaScript"> function transform(form) { proj4.defs([ ['WGS84', "+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees"], ['SWEREF99TM',"+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"] ]); var source='WGS84'; var target='SWEREF99TM'; var result = proj4(source, target, [form.sourceX.value, form.sourceY.value]); form.targetX.value = result[0]; form.targetY.value = result[1]; } </skript> </head> <body> <form> Källkoordinater:<br> X:<input name="sourceX" type=text size=10> Y:<input name="sourceY" type=text size=10><br> <small>(Omvandlar endast decimala Lat/Long till SWEREF99TM)</small><br> Målkoordinater:<br> X:<input name="targetX" type=text size=10> Y:<input name="targetY" type=text size=10><br><br> <button type=button onclick="transform(this.form)">Omvandla</button> </form> </body> </html>
(Observera att jag tvingats skriva ”script” med ”k” i koden ovan för att WordPress skall låta den passera opåverkad. Om du använder koden så måste du därför ändra alla skript till script.)
Tack, det var något jag letat efter länge!
För den ovane kan man ju tipsa om att syntaxen för att använda nätversionen av proj4.js är att ersätta
src=”proj4.js”
med
src=”https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.14/proj4.js”
om man inte vill ladda hem ett extra paket eller bråka med sökvägar.
Till min egentliga fråga, RT90-formatet lever ju trots allt väldigt aktivt i Sverige (räddningstjänst och kommuner tex) men det finns inte implementerat i proj4. På nätet finns förslag på parametersättningar som skulle funka, men jag får det inte ihop syntaxmässigt. Har du något tips för enklare användning?
/Andreas
Omvandling mellan koordinatsystem är lite trixigt med många parametrar för att det skall bli helt korrekt.
I QGIS används följande PROJ4 för att hantera RT90 2.5V (EPSG2400):
+proj=tmerc +lat_0=0 +lon_0=15.80827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +units=m +no_defs
När jag använder detta för att omvandla från WGS84 till RT90 så får jag samma svar med skriptet ovan som om jag använder online-tjänst från Lantmäteriet.
Jag antar således att transformationen är tillräckligt korrekt…
Kod (ersätt i exemplet ovan):
proj4.defs([
[’WGS84’, ”+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees”],
[’RT90′,”+proj=tmerc +lat_0=0 +lon_0=15.80827777777778 +k=1 +x_0=1500000 +y_0=0 +ellps=bessel +towgs84=414.1,41.3,603.1,-0.855,2.141,-7.023,0 +units=m +no_defs”]
]);
var source=’WGS84′;
var target=’RT90’;
På nedanstående länk har jag gjort ett exempel på hur man kan använda koden praktiskt för att omvandla till/från exempelvis RT90:
http://geosupportsystem.altervista.org/omvandla.html
Kanon, tack!
/Andreas