mirror of
https://github.com/mapillary/mapillary-js.git
synced 2026-01-25 14:07:28 +00:00
Migrate to Rollup. Emit umd, minified umd, module, type declarations and source maps. Work around problems with Falcor by using virtual module. Migrate to Jest. Run tests in with CommonJS modules becasue ES6 is not supported. Work around dependency problems by bootstrap to ensure they are not loaded during test. Remove all unused dependencies. Create state transition matrix to avoid circular dependencies. chore: tsc and rollup watch build chore: incremental watch build Remove unused dependencies. chore: use existing type packages chore: mock favicon chore: improve watch build chore: fix styles build chore: specific commonjs build for tests chore: reset spec files refactor: explicit state transition matrix chore: make src commands work chore: working unit tests and lib chore: add serve docs script chore: remove unused bundle config chore: refactor rollup config to avoid duplication fix: falcor imports fix: transition from source to target Fixes #87 Fixes #100 Fixes #159 Fixes #208
353 lines
12 KiB
HTML
353 lines
12 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
|
|
<head>
|
|
<title>MapillaryJS Map-Marker</title>
|
|
<link rel="icon" href="data:,">
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
|
|
|
|
<link rel="stylesheet" href="dist/mapillary.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({
|
|
apiClient: "QjI1NnU0aG5FZFZISE56U3R5aWN4ZzpkYzg0NzE3MDA0YTRhZjlh",
|
|
component: {
|
|
marker: { visibleBBoxSize: 100 },
|
|
mouse: { doubleClickZoom: false },
|
|
},
|
|
container: "mly",
|
|
});
|
|
|
|
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>
|