Last active
June 7, 2021 12:10
-
-
Save oscarlorentzon/16946cb9eedfad2a64669cb1121e6c75 to your computer and use it in GitHub Desktop.
LatLon, computedLatLon and originalLatLon explained
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE HTML> | |
<html> | |
<head> | |
<meta charset='utf-8' /> | |
<title></title> | |
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> | |
<link href='https://unpkg.com/[email protected]/dist/mapillary.min.css' rel='stylesheet' /> | |
<link href='https://unpkg.com/[email protected]/dist/leaflet.css' rel='stylesheet' /> | |
<script src='https://unpkg.com/[email protected]/dist/mapillary.min.js'></script> | |
<script src='https://unpkg.com/[email protected]/dist/leaflet.js'></script> | |
<style> | |
body { margin:0; padding:0; height: 100%; } | |
#mly { position: absolute; height: 100%; width: 66%; } | |
#map { position: absolute; width: 34%; top: 0; right: 0; bottom: 0; } | |
</style> | |
</head> | |
<body> | |
<div id='mly'></div> | |
<div id='map'></div> | |
<script> | |
var map = L.map('map').setView([55.608725, 13.0343], 19); | |
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; | |
var osmAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'; | |
var osm = new L.TileLayer(osmUrl, { maxZoom: 19, attribution: osmAttrib}); | |
map.addLayer(osm); | |
var mly = new Mapillary.Viewer({ | |
apiClient: 'QjI1NnU0aG5FZFZISE56U3R5aWN4Zzo3NTM1MjI5MmRjODZlMzc0', | |
component: { cover: false }, | |
container: 'mly', | |
imageKey: 'dZ8LOXMF4c3c8IhplqcjNw', | |
}); | |
function setMarkerLatLng(marker, latLng) { | |
marker.setLatLng(latLng); | |
if (!map.hasLayer(marker)) { | |
marker.addTo(map); | |
} | |
} | |
/** | |
* When images are uploaded they will have GPS information in the EXIF, this is what | |
* we call `originalLatLon` on the Node class in MapillaryJS | |
* (https://mapillary.github.io/mapillary-js/classes/node.html#originallatlon). | |
* | |
* When Structure from Motions has been run for a node a `computedLatLon` that | |
* differs from the `originalLatLon` will be created. It is different because | |
* GPS positions are not very exact and SfM aligns the camera positions according | |
* to the 3D reconstruction | |
* (https://mapillary.github.io/mapillary-js/classes/node.html#computedlatlon). | |
* | |
* At last there exist a `latLon` property in MapilllaryJS which evaluates to | |
* the `computedLatLon` from SfM if it exists but falls back to the `originalLatLon` | |
* from the EXIF GPS otherwise | |
* (https://mapillary.github.io/mapillary-js/classes/node.html#latlon) | |
* Everything that is done in in the MapillaryJS Viewer is based on the SfM positions, | |
* i.e. `computedLatLon`. That is why the smooth transitions go in the right | |
* direction (and not strange directions because of bad GPS). | |
* | |
* E.g. when placing a marker in the Viewer it is relative to the SfM | |
* position i.e. the `computedLatLon`. | |
* | |
* The same concept as above also applies to the compass angle (or bearing) properties | |
* `originalCa`, `computedCa` and `ca` on the Node class. | |
*/ | |
// Show a red marker for the original EXIF GPS position, | |
// a blue marker for the SfM computed position and a | |
// small yellow marker for the `latLon` property. | |
var originalLatLngMarker = L.circleMarker([0, 0], { radius: 8, color: '#f00', fillOpacity: 1, opacity: 1 }); | |
var computedLatLngMarker = L.circleMarker([0, 0], { radius: 8, color: '#00f', fillOpacity: 1, opacity: 1 }); | |
var latLngMarker = L.circleMarker([0, 0], { radius: 3, color: '#ff0', fillOpacity: 1, opacity: 1 }); | |
mly.on(Mapillary.Viewer.nodechanged, function (node) { | |
// Set the position of the marker related to the original EXIF GPS | |
// position which always exist. | |
var originalLatLng = [node.originalLatLon.lat, node.originalLatLon.lon]; | |
setMarkerLatLng(originalLatLngMarker, originalLatLng); | |
// Check if node has been merged (SfM has been run). | |
if (node.merged) { | |
// If SfM has been run, computed SfM position exists so | |
// set position and add to map. | |
var computedLatLng = [node.computedLatLon.lat, node.computedLatLon.lon]; | |
setMarkerLatLng(computedLatLngMarker, computedLatLng); | |
} else { | |
// If SfM has not been run, computed SfM position does not exist | |
// so remove SfM computed marker from map for this node. | |
if (map.hasLayer(computedLatLngMarker)) { | |
map.removeLayer(computedLatLngMarker); | |
} | |
} | |
var latLng = [node.latLon.lat, node.latLon.lon]; | |
setMarkerLatLng(latLngMarker, latLng); | |
map.setView(latLng); | |
}); | |
window.addEventListener('resize', function() { mly.resize(); }); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment