Mappedin MapLibre Overlay
Using Mappedin JS with your own map requires a Pro license. Try a demo map for free or refer to the Pricing page for more information.
Mappedin JS makes use of MapLibre to render the outdoor portion of the map. The SDK exposes this layer through MapView.Outdoor and can be used to add additional MapLibre layers as described in the Outdoor Map Guide.
It is also possible to utilize the opposite architecture, by adding a MapView to a MapLibre Map. This is accomplished by using Mappedin MapLibre Overlay package @mappedin/maplibre-overlay, which is a standalone package that can be used in conjunction with Mappedin JS and made available as a NPM package.
In most cases, it is recommended to use the Mappedin JS package and not the Mappedin MapLibre Overlay package. The Mappedin MapLibre Overlay is only recommended for the following use cases:
- When adding Mappedin to an existing MapLibre application.
- When multiple maps that are larger distances (5+ km) apart are needed to be displayed on the same map.
Installation
The version of the @mappedin/maplibre-overlay package must match the version of the @mappedin/mappedin-js package.
Mappedin MapLibre Overlay is provided as a separate package that works in conjunction with Mappedin JS. To install the @mappedin/maplibre-overlay package from npm, run the following command:
With NPM:
npm install @mappedin/maplibre-overlay
With Yarn:
yarn add @mappedin/maplibre-overlay
Usage
Set centerClampedToGround: false when using multi-floor view. MapLibre defaults centerClampedToGround to true, which resets the camera elevation to 0 every frame. This prevents floor elevation changes from taking effect. This must be set to false when constructing the MapLibre map when multiFloorView is enabled.
const map = new MapLibreMap({
container: 'map',
centerClampedToGround: false, // required for multi-floor view
// ...other options
});
The following example demonstrates the use of the @mappedin/maplibre-overlay package. A MapLibre Map is created, using the indoor map's center point as it's initial position. Once the MapLibre map is loaded, a MappedinMapLibreOverlay is added using the MapLibre addControl method.
When the map is clicked, the current MappedinMapLibreOverlay is removed and a new one added to show an indoor map of a different building. The map is then moved to the center point of the new indoor map.
The CodeSandbox above uses the following code:
import { getMapData, MapView } from "@mappedin/mappedin-js";
import {
createMapLibreOverlay,
MappedinMapLibreOverlay,
} from "@mappedin/maplibre-overlay";
import { Map as MapLibreMap } from "maplibre-gl";
import "./styles.css";
async function init() {
// See Trial API key Terms and Conditions
// https://developer.mappedin.com/docs/demo-keys-and-maps
const KEY = "mik_yeBk0Vf0nNJtpesfu560e07e5";
const SECRET = "mis_2g9ST8ZcSFb5R9fPnsvYhrX3RyRwPtDGbMGweCYKEq385431022";
// Get MapData for 2 maps.
const maps = await Promise.all([
await getMapData({
key: KEY,
secret: SECRET,
mapId: "660c0c3aae0596d87766f2da",
}),
await getMapData({
key: KEY,
secret: SECRET,
mapId: "660c0c6e7c0c4fe5b4cc484c",
}),
]);
let currentOverlay: MappedinMapLibreOverlay;
// Instantiate a MapLibreMap and center it on the first indoor map's center point.
// Use Mappedin's default outdoor style.
const map = new MapLibreMap({
container: "mappedin-map",
style: "https://tiles-cdn.mappedin.com/styles/mappedin/style.json",
center: [maps[0].mapCenter.longitude, maps[0].mapCenter.latitude],
zoom: 18,
centerClampedToGround: false, // required for multi-floor view
transformRequest: (url: string) => {
return {
url: url,
headers: {
"x-mappedin-tiles-key": maps[0].outdoorViewToken,
},
};
},
});
// Once the MapLibreMap is loaded, add a MappedinMapLibreOverlay to display
// the indoor map.
map.on("load", () => {
currentOverlay = createMapLibreOverlay(maps[0]);
map.addControl(currentOverlay);
currentOverlay.on("loaded", async ({ mapView }: { mapView: MapView }) => {
mapView.__EXPERIMENTAL__auto();
map.flyTo({
center: [maps[0].mapCenter.longitude, maps[0].mapCenter.latitude],
curve: 1.42,
});
});
});
let i = 1;
// When the map is clicked, fly to the other indoor map's center point
// and display it.
map.on("click", async () => {
const mapData = maps[i];
// Remove the existing MappedinMapLibreOverlay.
if (currentOverlay) {
map.removeControl(currentOverlay);
}
currentOverlay = createMapLibreOverlay(mapData);
// Add the other indoor map and move the camera to its location.
map.addControl(currentOverlay);
currentOverlay.on("loaded", async ({ mapView }: { mapView: MapView }) => {
mapView.__EXPERIMENTAL__auto();
map.easeTo({
center: [mapData.mapCenter.longitude, mapData.mapCenter.latitude],
zoom: 18,
duration: 2000,
});
});
i++;
if (i >= maps.length) {
i = 0;
}
});
}
init();