UNPKG

mapillary-js

Version:

WebGL JavaScript library for displaying street level imagery from mapillary.com

340 lines (266 loc) 13.1 kB
<!DOCTYPE HTML> <html> <head> <meta charset='utf-8' /> <title></title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' /> <link rel='stylesheet' href='dist/mapillary.min.css' /> <link href='https://unpkg.com/leaflet@1.0.1/dist/leaflet.css' rel='stylesheet' /> <script src='dist/mapillary.js'></script> <script src='https://unpkg.com/leaflet@1.0.1/dist/leaflet.js'></script> <style> body { margin:0; padding:0; height: 100%; } #mly { position: absolute; width: 60%; height: 100%; } #map { position: absolute; width: 40%; height: 100%; right: 0; } </style> </head> <body> <div id='mly'></div> <div id='map'></div> <script> // Setup map const map = L.map('map').setView([56.04351888068181, 12.695600612967427], 18); const osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; const osmAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'; const osm = new L.TileLayer(osmUrl, { maxZoom: 19, attribution: osmAttrib}); map.addLayer(osm); map.keyboard.disable(); // Setup viewer const mly = new Mapillary.Viewer( 'mly', 'QjI1NnU0aG5FZFZISE56U3R5aWN4ZzowODkzY2RjNjM1ZmEwYTVi', null, { component: { marker: { visibleBBoxSize: 100, }, mouse: { doubleClickZoom: false, }, stats: false, }, }); mly.moveToKey('6Zhtztzt67fWmdd4OYH44w').then( () => { /* noop */ }, (e) => { console.error(e); }); // Show original latLon and latLon (if computed exist it will differ) of current // viewer node on map. Show line linking the two points together const mapNodePosition = { line: L.polyline([[0, 0], [0, 0]], {color: '#0ff', weight: 1}), originalPos: L.circleMarker([0, 0], { radius: 7, color: '#0ff' }), pos: L.circleMarker([0, 0], { radius: 7, color: '#00f' }), }; mly.on(Mapillary.Viewer.nodechanged, (node) => { const latLon = [node.latLon.lat, node.latLon.lon]; const originalLatLon = [node.originalLatLon.lat, node.originalLatLon.lon]; mapNodePosition.line.setLatLngs([originalLatLon, latLon]); mapNodePosition.originalPos.setLatLng(originalLatLon); mapNodePosition.pos.setLatLng(latLon); map.setView(latLon); if (!map.hasLayer(mapNodePosition.line)) { mapNodePosition.line.addTo(map); mapNodePosition.originalPos.addTo(map); mapNodePosition.pos.addTo(map); } }); // Get marker component const markerComponent = mly.getComponent('marker'); // Show a flat circle marker in the viewer when hovering the map let mapHoverViewerMarker; const removeMapHoverViewerMarker = () => { if (!!mapHoverViewerMarker && markerComponent.has(mapHoverViewerMarker.id)) { markerComponent.remove([mapHoverViewerMarker.id]); mapHoverViewerMarker = null; } } const onMapMouseEvent = (e) => { mapHoverViewerMarker = new Mapillary.MarkerComponent.CircleMarker( 'map-hover-viewer-marker-id', { lat: e.latlng.lat, lon: e.latlng.lng }, { color: '#0f0' }); markerComponent.add([mapHoverViewerMarker]); } map.on('mousemove', onMapMouseEvent); map.on('mouseover', onMapMouseEvent); map.on('mouseout', removeMapHoverViewerMarker); // Show a flat circle marker in the viewer and a corresponding map marker when hovering the viewer const indicator = { id: "indicator-id", mapLine: L.polyline([[0, 0], [0, 0]], { color: '#0f0', weight: 1, id: "indicator-id-line" }), mapMarker: L.circleMarker([0, 0], { radius: 5, color: '#0f0', id: "indicator-id-circle" }), viewerMarker: null, state: { dragging: false, lastPos: null, moving: false, }, }; const addMapIndicator = () => { if (!map.hasLayer(indicator.mapLine)) { indicator.mapLine.addTo(map); } if (!map.hasLayer(indicator.mapMarker)) { indicator.mapMarker.addTo(map); } } const removeMapIndicator = () => { if (map.hasLayer(indicator.mapLine)) { map.removeLayer(indicator.mapLine); } if (map.hasLayer(indicator.mapMarker)) { map.removeLayer(indicator.mapMarker); } } const removeViewerIndicator = () => { if (!!indicator.viewerMarker && markerComponent.has(indicator.viewerMarker.id)) { markerComponent.remove([indicator.viewerMarker.id]); indicator.viewerMarker = null; } } const setViewerIndicatorMarker = (latLon) => { const viewerMarker = new Mapillary.MarkerComponent.CircleMarker( indicator.id, latLon, { color: '#0f0' }); markerComponent.add([viewerMarker]); indicator.viewerMarker = viewerMarker; } const moveIndicatorMarker = (latLon) => { if (indicator.state.dragging) { return; } if (latLon == null) { removeMapIndicator(); removeViewerIndicator(); return; } const posLatLng = mapNodePosition.pos.getLatLng(); const lineString = [ [posLatLng.lat, posLatLng.lng], [latLon.lat, latLon.lon], [ posLatLng.lat + 5 * (latLon.lat - posLatLng.lat), posLatLng.lng + 5 * (latLon.lon - posLatLng.lng), ], ]; indicator.mapLine.setLatLngs(lineString); indicator.mapMarker.setLatLng([latLon.lat, latLon.lon]); setViewerIndicatorMarker({ lat: latLon.lat, lon: latLon.lon }); addMapIndicator(); } const onViewerMouseEvent = (event) => { indicator.state.lastPos = event.pixelPoint; moveIndicatorMarker(event.latLon); } mly.on(Mapillary.Viewer.mouseup, onViewerMouseEvent); mly.on(Mapillary.Viewer.mouseover, onViewerMouseEvent); mly.on(Mapillary.Viewer.mousedown, onViewerMouseEvent); mly.on(Mapillary.Viewer.mousemove, (event) => { // Store last mouse position for later unprojection indicator.state.lastPos = event.pixelPoint; if (indicator.state.moving || indicator.state.dragging) { return; } moveIndicatorMarker(event.latLon); }); mly.on(Mapillary.Viewer.mouseout, (event) => { indicator.state.lastPos = null; removeViewerIndicator(); removeMapIndicator(); }); mly.on(Mapillary.Viewer.movestart, (event) => { indicator.state.moving = true; }); mly.on(Mapillary.Viewer.moveend, (event) => { indicator.state.moving = false; if (!indicator.state.lastPos) { return; } // Unproject the last position and move indicator marker if latLon exist mly.unproject(indicator.state.lastPos).then(moveIndicatorMarker); }); markerComponent.on(Mapillary.MarkerComponent.MarkerComponent.dragstart, () => { // Remove indicators when dragging marker in the viewer indicator.state.dragging = true; removeViewerIndicator(); removeMapIndicator(); }); markerComponent.on(Mapillary.MarkerComponent.MarkerComponent.dragend, () => { indicator.state.dragging = false; if (!indicator.state.lastPos) { return; } // Unproject the last position and move indicator marker if latLon exist mly.unproject(indicator.state.lastPos).then(moveIndicatorMarker); }); // Create markers on click in map or viewer let addedMarkerId = 0; const mapMarkers = {}; const addOrReplaceViewerMarker = (id, latLon) => { // Create an interactive marker to be able to drag it in viewer // and retrieve it with getMarkerIdAt method const marker = new Mapillary.MarkerComponent.SimpleMarker( id, latLon, { ballColor: '#f00', color: '#f00', interactive: true }); markerComponent.add([marker]); } const handleMapMarkerDrag = (mapMarker) => { // Listen to map events and act to move map and viewer markers accordingly mapMarker.on({ mousedown: (event) => { const onMouseMove = (e) => { // Update both viewer marker and map marker on map marker drag addOrReplaceViewerMarker(mapMarker.options.id, { lat: e.latlng.lat, lon: e.latlng.lng }); mapMarker.setLatLng(e.latlng); }; const onMouseUp = (e) => { map.off('mousemove', onMouseMove) map.off('mouseup', onMouseUp); } map.on('mousemove', onMouseMove); map.on('mouseup', onMouseUp); }, mouseover: (event) => { // Remove map hover viewer marker when hovering a map marker removeMapHoverViewerMarker(); // Disable map dragging to ensure that only map marker is dragged map.dragging.disable(); map.off('mousemove', onMapMouseEvent); map.off('click', mapOnClick); }, mouseout: (event) => { map.dragging.enable(); map.on('mousemove', onMapMouseEvent); map.on('click', mapOnClick); }, }); } const createMarker = (latLon) => { const id = (addedMarkerId++).toString(); addOrReplaceViewerMarker(id, latLon); const mapMarker = L.circleMarker( [latLon.lat, latLon.lon], { radius: 5, color: '#f00', draggable: 'true', id: id }) .addTo(map); mapMarkers[id] = mapMarker; handleMapMarkerDrag(mapMarker); } mly.on(Mapillary.Viewer.click, (e) => { if (!e.latLon) { return; } markerComponent.getMarkerIdAt(e.pixelPoint).then((markerId) => { // Only create a new marker if no interactive markers are hovered if (markerId != null) { return; } createMarker(e.latLon); }); }); const mapOnClick = (e) => { if (!e.latlng) { return; } createMarker({ lat: e.latlng.lat, lon: e.latlng.lng }); }; map.on('click', mapOnClick); // Update map marker when latLon changes for a marker by dragging in the viewer markerComponent.on(Mapillary.MarkerComponent.MarkerComponent.changed, (e) => { const mapMarker = mapMarkers[e.marker.id]; if (!mapMarker) { return; } mapMarker.setLatLng([e.marker.latLon.lat, e.marker.latLon.lon]); }); // Trigger render on browser window resize window.addEventListener('resize', () => { mly.resize(); }); </script> </body> </html>