mapillary-js/debug/leaflet.html
Oscar Lorentzon b562a0b06c chore: build with rollup
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
2021-03-15 11:23:22 +01:00

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>