Getting a link to a map fragment
vanilla.html
react.html
vue.html
common.ts
variables.ts
sandbox.json
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://js.api.mappable.world/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="../variables.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
import type {
BehaviorMapEventHandler,
LngLat,
MMapCenterLocation,
MMapLocationRequest,
MMapZoomLocation
} from '@mappable-world/mappable-types';
import {getQueryParams, updateQueryParams} from './common';
import {LOCATION} from '../variables';
window.map = null;
main();
async function main() {
// Waiting for all api elements to be loaded
await mappable.ready;
const {MMap, MMapDefaultSchemeLayer, MMapListener} = mappable;
let mapLocation: MMapLocationRequest = LOCATION;
const currentCenter = getQueryParams('spn');
const currentZoom = getQueryParams('z');
if (currentCenter) {
(mapLocation as MMapCenterLocation).center = currentCenter.split(',').map(parseFloat) as LngLat;
}
if (currentZoom) {
(mapLocation as MMapZoomLocation).zoom = parseFloat(currentZoom);
}
// Initialize the map
map = new MMap(
// Pass the link to the HTMLElement of the container
document.getElementById('app'),
// Pass the map initialization parameters
{location: mapLocation, showScaleInCopyrights: true},
// Add a map scheme layer
[new MMapDefaultSchemeLayer({})]
);
// Handler function for changing the status of the onActionEnd event
const updateHandler: BehaviorMapEventHandler = (object) => {
const setNewMapLocation = _.debounce(() => {
updateQueryParams('spn', object.location.center.map((langLat) => langLat.toFixed(6)).join(','));
updateQueryParams('z', object.location.zoom.toString());
}, 250);
setNewMapLocation();
};
/* Add a listener to the map and pass the handlers functions for the events you want to process
These are just some of the events, you can see them all in the documentation */
map.addChild(
new MMapListener({
onActionEnd: updateHandler
})
);
}
</script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
</head>
<body>
<div id="app"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/react-dom@17/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<!-- To make the map appear, you must add your apikey -->
<script src="https://js.api.mappable.world/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="react, typescript"
type="text/babel"
src="../variables.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="react, typescript"
type="text/babel"
src="./common.ts"
></script>
<script data-plugins="transform-modules-umd" data-presets="react, typescript" type="text/babel">
import type {BehaviorMapEventHandler, LngLat, MMapLocationRequest} from '@mappable-world/mappable-types';
import {getQueryParams, updateQueryParams} from './common';
import {LOCATION} from '../variables';
window.map = null;
main();
async function main() {
// For each object in the JS API, there is a React counterpart
// To use the React version of the API, include the module @mappable-world/mappable-reactify
const [mappableReact] = await Promise.all([mappable.import('@mappable-world/mappable-reactify'), mappable.ready]);
const reactify = mappableReact.reactify.bindTo(React, ReactDOM);
const {MMap, MMapDefaultSchemeLayer, MMapDefaultFeaturesLayer, MMapListener} = reactify.module(mappable);
const {useState, useCallback, useEffect} = React;
function App() {
const [mapLocation, setMapLocation] = useState<MMapLocationRequest>(LOCATION);
// Handler function for changing the status of the onUpdate event
const updateHandler: BehaviorMapEventHandler = useCallback((object) => {
const setNewMapLocation = _.debounce(() => {
updateQueryParams('spn', object.location.center.map((latLang) => latLang.toFixed(6)).join(','));
updateQueryParams('z', object.location.zoom.toString());
}, 250);
setNewMapLocation();
}, []);
useEffect(() => {
const currentCenter = getQueryParams('spn');
const currentZoom = getQueryParams('z');
if (currentCenter) {
setMapLocation((state) => ({
...state,
center: currentCenter.split(',').map(parseFloat) as unknown as LngLat
}));
}
if (currentZoom) {
setMapLocation((state) => ({
...state,
zoom: parseFloat(currentZoom)
}));
}
}, []);
return (
<MMap location={mapLocation} showScaleInCopyrights={true} ref={(x) => (map = x)}>
<MMapDefaultSchemeLayer />
<MMapDefaultFeaturesLayer />
{/* Add a listener to the map and pass the handlers functions for the events you want to process
These are just some of the events, you can see them all in the documentation */}
<MMapListener onActionEnd={updateHandler} />
</MMap>
);
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('app')
);
}
</script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
</head>
<body>
<div id="app"></div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<script crossorigin src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script src="https://js.api.mappable.world/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="../variables.ts"
></script>
<script
data-plugins="transform-modules-umd"
data-presets="typescript"
type="text/babel"
src="./common.ts"
></script>
<script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
import type {LngLat, MMapCenterLocation, MMapLocationRequest, MMapZoomLocation} from '@mappable-world/mappable-types';
import {getQueryParams, updateQueryParams} from './common';
import {LOCATION} from '../variables';
window.map = null;
async function main() {
// For each object in the JS API, there is a Vue counterpart
// To use the Vue version of the API, include the module @mappable-world/mappable-vuefy
const [mappableVue] = await Promise.all([mappable.import('@mappable-world/mappable-vuefy'), mappable.ready]);
const vuefy = mappableVue.vuefy.bindTo(Vue);
const {MMap, MMapDefaultSchemeLayer, MMapListener} = vuefy.module(mappable);
const app = Vue.createApp({
components: {
MMap,
MMapDefaultSchemeLayer,
MMapListener
},
setup() {
const refMap = (ref) => {
window.map = ref?.entity;
};
const mapLocation = Vue.ref<MMapLocationRequest>(LOCATION);
const currentCenter = getQueryParams('spn');
const currentZoom = getQueryParams('z');
if (currentCenter) {
(mapLocation.value as MMapCenterLocation).center = currentCenter.split(',').map(parseFloat) as LngLat;
}
if (currentZoom) {
(mapLocation.value as MMapZoomLocation).zoom = parseFloat(currentZoom);
}
return {
mapLocation,
LOCATION,
updateQueryParams,
getQueryParams,
refMap
};
},
methods: {
updateHandler(object) {
const setNewMapLocation = _.debounce(() => {
this.updateQueryParams(
'spn',
object.location.center.map((langLat) => langLat.toFixed(6)).join(',')
);
this.updateQueryParams('z', object.location.zoom.toString());
}, 250);
setNewMapLocation();
}
},
template: `
<!-- Initialize the map and pass initialization parameters -->
<MMap :location="mapLocation" :showScaleInCopyrights="true" :ref="refMap">
<!-- Add a map scheme layer -->
<MMapDefaultSchemeLayer/>
<!-- Add a listener to the map and pass the handlers functions for the events you want to process
These are just some of the events, you can see them all in the documentation -->
<MMapListener :onActionEnd="updateHandler" />
</MMap>`
});
app.mount('#app');
}
main();
</script>
<!-- prettier-ignore -->
<style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; } </style>
</head>
<body>
<div id="app"></div>
</body>
</html>
export const updateQueryParams = (key: string, value: string) => {
const url = new URL(window.location as unknown as string);
url.searchParams.set(key, value);
window.history.replaceState({}, '', url);
};
export const getQueryParams = (key: string) => {
const url = new URL(window.location as unknown as string);
return url.searchParams.get(key);
};
import type {MMapLocationRequest} from '@mappable-world/mappable-types';
export const LOCATION: MMapLocationRequest = {
center: [55.44279, 25.24613], // starting position [lng, lat]
zoom: 11 // starting zoom
};
{"node": 20, "template": "static"}