Till att börja med så får jag säga att jag inte riktigt är i mål med det jag beskriver här. Det blir därför inte superdetaljerat, men jag tänkte i alla fall visa vad det är jag tänkt mig och hur långt jag kommit. Det blir dessutom ett inlägg i två delar där avslutningen kommer först i morgon.
Jag har varit inne på det jag skall beskriva här tidigare, och då frågat efter om någon var sugen på lite javaskriptprogrammering. Nu vill jag väl inte kalla mig själv programmerare, men jag tröttnade lite på att vänta på att någon annan skulle göra jobbet så nu har jag börjat ta fram en DEMO själv!
Vad handlar det då om? Har ni sett exempelvis Trimble MX7? (länk)
Vad det handlar om är system där man använder georefererade panoramabilder fångade med kalibrerade kameror av hög kvalité och positionerade med mycket hög noggrannhet med GPS mottagare med RTK korrektioner. Ur den data som samlas in kan man sedan i efterhand hämta mått och positioner på det som syns i bilderna.
Dessa system löser sina uppgifter på ett utmärkt sätt. Problemet är priset. Utan att veta vad MX7 kostar så kan vi säga att om den kostar 100’000 kr så är det 100’000 kr för mycket för mig…
Jag räknar inte med att komma i närheten av den kvalité, noggrannhet och säkerhet som man uppnår med dessa system, men det behöver jag inte heller. Genom att använda sådant jag redan har och Open Source så kanske jag kan skapa något som blir tillräckligt bra för exakt 0 kr.
Panoraman
För att ha något att börja med så behövs det panoramabilder. Rent tekniskt så kan vilka bilder som helst användas, men 360 graders panoraman är bra och underlättar en hel del i skrivandet av koden för det jag tänkt. Det behöver inte vara helt sfäriska panoraman så länge man inte skall mäta i höjd, vilket jag inte tänkt till att börja med.
Jag har tidigare byggt en ”robot” som fångar panoramabilder som blir av mycket hög kvalité och jag har provat mina skript med denna typ av bilder och det fungerar ganska bra. Här har jag tänkt prova med en vanlig smart telefon och en panorama-app (Photosynth).
Oavsett hur man skapar sina panoraman så skall resultatet vara en bild som sträcker sig hela horisonten runt, gärna ”ekvirektilinjär” projektion. Dessutom så skall skarven vara orienterad rakt mot norr.
Det skulle gå att ha norr åt vilket håll som helst så länge man vet var. För enkelhetens skull så använder jag dock denna begränsning och slipper därmed skapa eller modifiera EXIF informationen i filerna. Jag vill nämligen att all erforderlig data om panoramat skall finnas inbyggt i filen. Den andra förutsättningen med panoramat är att dessa är geotaggade med GPS-position. Detta löser appen i telefonen, men noggrannheten blir ju därefter. När jag fångat panoraman med min robot så har jag medelberäknat positionen med en hand-GPS av skaplig kvalité, vilket också spelar in på slutresultatet. Har man inte med koordinaterna i filen så skall man ändå kunna ange dessa manuellt i gränssnittet.
Är skarven i panoramat inte exakt mot norr så kan man justera detta i ett ritprogram. Kopiera bara det som är till ”vänster” om norr, flytta bilden så att norr hamnar vid vänsterkanten och klistra in det som kopierats längst till höger. Inte så mycket jobb, och därmed är panoramat färdigbehandlat.
Matte
Ja så är det. Jobbar man med GIS och kartor så måste man kunna hantera matematik. Nu är det inte särskilt komplicerat men om man sov på trigonometrilektionerna eller ”bara” läste Matte-A så kan det bli lite krångligt.
Är du osäker så kommer här en kort förklaring. Panoraman är tagna vid punkt A och punkt B, dessa har en känd position i och med att bilderna är geotaggade.
Med hjälp av skillnaden i East och North mellan punkterna så får vi en triangel med hypotenusan A-B. Då kan vi räkna ut avståndet mellan A och B med Pythagoras sats, om vi vill, men här behövs det inte.
I varje panorama så pekar vi ut en punkt som ger oss en vinkel v i förhållande till norr. Vinklarna i bilderna skapar en skärningspunkt någonstans (C) och det är denna skärningspunkt som vi är intresserade av.
Jag använder punkten A för mitt exempel, men samma princip gäller även för B (och C).
Linjen A-C, och alla raka linjer, baseras på en formel som om man anpassar den till koordinatsystemet lyder:
North = k * East + m
Konstanten k (linjens lutning) kan beräknas med:
k = tan ( 90 – v )
Eftersom vi känner till East och North i en punkt (nämligen A) så kan vi sedan räkna fram m (var skär linjen Y axeln) med den första formeln.
Samma sak kan göras för linjen B-A och sedan vidtar räknandet för att lista ut var dessa två linjer skär varandra (i C).
Använder vi de båda linjernas formler för att beskriva punkten C så får vi:
North(C) = k(A) * East(C) + m(A)
North(C) = k(B) * East(C) + m(B)
De enda obekanta här är North(C) och East(C), men vi vet att Nort(C) = North(C) och att East(C) = East(C). Ersätter vi North(C) i den ena formeln med innehållet i den andra så får vi:
k(A) * East(C) + m(A) = k(B) * East(C) + m(B)
East(C) ( k(A) – k(B) ) = m(B) – m(A)
East(C) = ( m(B) – m(A) ) / ( k(A) – k(B) )
När vi räknat ut East(C) så kan vi använda någon av de första formlerna för att räkna ut North(C). Enkelt eller hur…
Webbsidan
Nu när matten är avklarad så behöver allt kläs i ett webbgränssnitt.
Koden bakom denna får dock vänta till i morgon…
(Spänningen är oliiiidlig!)
Varför Leaflet i detta fall? Känns inte som det är helt lämpat för detta, three.js + egen lösning för koordinaterna känns lättare, men åt ena sidan så vet jag inte vilka plugin du hittat för ändamålet.
Jag får erkänna att jag inte provat något direkt alternativ. Leaflet åstadkommer exakt det jag vill med ganska lite kod, men sedan kanske three.js är bättre på något annat sätt?