mirror of
https://github.com/mapillary/mapillary-js.git
synced 2026-01-18 13:56:53 +00:00
This results in a css file size that is 25 kb larger than before. We determine that it is negligible compared to library usage data size.
354 lines
12 KiB
HTML
354 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.moveTo("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("node", (event) => {
|
|
const node = event.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("mouseup", onViewerMouseEvent);
|
|
mly.on("mouseover", onViewerMouseEvent);
|
|
mly.on("mousedown", onViewerMouseEvent);
|
|
|
|
mly.on("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("mouseout", () => {
|
|
indicator.state.lastPos = null;
|
|
removeViewerIndicator();
|
|
removeMapIndicator();
|
|
});
|
|
|
|
mly.on("movestart", () => { indicator.state.moving = true; });
|
|
mly.on("moveend", () => {
|
|
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("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>
|