mapview-js
Interactive map viewer with 2D and 3D support.
Local Usage
To run your own instance of the demo page (to test how things will look if you make changes in CMS, for example) just follow these steps:
- Clone the repo
npm install
- (Optional) If you want to point to staging, open examples/index.js and add
baseUrl: https://api-staging.mappedin.com/1/,
to the options
object in the doInit
functionnpm run dev
to start the dev server. This will open the browser for you.- Put your credentials, venue slug and perspective in the settings box on the left and hit submit.
- (Optional) If you are going to be using this tool often copy
examples/MappedinConfig.template.js
to examples/MappedinConfig.js
and put your credentials in there.
If you need credentials, or have any other questions. talk to Paul.
Releasing
To cut a fresh release, you must update the npm version and tag it in github. The Jenkins job will publish the release externally and update the private NPM repo.
- Ensure you are on the latest Master branch
- npm version [major|minor|patch], ie
npm version minor
- git checkout -b , ie
git checkout -b 1.30.0
- git push origin --follow-tags, ie
git push origin 1.30.0 --follow-tags
- PR your branch back into master for the normal review process
- Once it's merged, tag a release with release notes
- Build the websdk-production job in Jenkins, using your new version tag as the parameter
- Send release notes to Ian for publication on the KB and alerts to partners.
Integration
The demo is useful for testing, shows how the mapview is supposed to be used, and does some neat demos. However, you probably want to actually integrate mappedin.js into your application itself. It is built to either be script tagged or required in.
To setup the map view, you must first perform a test to determine whether the browser can handle 3D or not, or force the mode of the viewer. Either way, first setup an init function that can be called in either situation.
var init = function(error, success) {
Mappedin.init(options, function(error, success) {
if (error) {
console.log('Mappedin error', error);
}
else {
initWithData(success);
}
}
}
We wrap the Mappedin.init
function in our own because the callback in the upcoming functions passes in the error
and success
parameters. This way we can pass in an options object as well. The options object contains your access info, API fields to fetch and things like which venue and perspective you want to work with.
The easiest way to handle the cases is to read a parameter and use a switch statement to get the program going. In this example, the parameter forceMode
is taken from the URL, and uses the init
function from above.
switch(forceMode) {
case '2d':
case '2D':
Mappedin.force2D(init);
break;
case '3d':
case '3D':
Mappedin.force3D(init);
break;
case 'test':
Mappedin.forceTest(canvas, init);
break;
default:
Mappedin.test3D(canvas, init);
}
If successful, success
in init
will contain the data you want to proceed with. You can access it in the callback like so:
function initWithData(response) {
var data = response._data;
In this function we will also call for the map view.
function initWithData(response) {
data = response._data;
var mapViewOptions = {
onDataLoaded: initPostMapLoaded
};
mapView = new Mappedin.MapView(canvas, data, mapViewOptions);
}
The MapView constructor takes your container (just a div
, you can use document.getElementById
or similar to access it), your data, and an options object. Options are optional, just pass a null
to use the defaults. One useful option is the onDataLoaded
callback to work with when your maps and data are all ready to go.
In your callback you have a chance to override some functions to create the behaviour you want. Most notably, you will want to override onPolygonClicked
and onNothingClicked
.
function mapLoaded() {
mapView.onNothingClicked() {
mapView.clearAllPolygonColors();
}
mapView.onPolygonClicked = function(polygon) {
mapView.clearAllPolygonColors();
mapView.setPolygonColor(polygon, 0xff0000, true);
return false;
}
}
This is also the place you want to define your interactive polygons. To do this, we can just simply loop through the locations and their polygons, using MapView's addInteractivePolygon
. Typically these will be polygons that have a location associated with them, though you may also want to look at polygons that have an entrance node. The latter should be a superset of the former, including polygons that are currently vacant.
var locations = data.locations;
for (var i = 0, iLen = locations.length; i < iLen; ++i) {
var location = locations[i];
var polygons = location.polygons;
for (var j = 0, jLen = polygons.length; j < jLen; ++j) {
var polygon = polygons[i];
mapView.addInteractivePolygon(polygon);
}
}
This should be enough to get a basic map view running.
Helper Functions
One thing useful in creating custom behaviours in your map view is being able to get specific data when you need it. These functions utilize lodash's find
function to sift through the data. Since we don't need most of the library, it is useful to only include the pieces that do get used. In these examples, the program is compiled by Babel and is using ES6 syntax. We include find via import find from 'lodash.find'
.
const getLocationByPolygonId = (pid) => {
return find(venue.locations, (location) => {
return find(location.polygons, { 'id': pid });
});
};
const getLocationById = (lid) => {
return find(venue.locations, { 'id': lid });
};
const getPolygonInLocationId = (pid, location) => {
return find(location.polygons, { 'id': pid });
};
const getNodeByPolygonMap = (mid, location) => {
return find(location.nodes, { 'map': mid });
};
const getMapById = (mid) => {
return find(venue.maps, { 'id': mid });
};
Drawing Directions
Part of the location data structure is a directionsTo
function to get data we can use to draw paths on our maps. To get the data you can use two location objects and the API will figure out the best entrance nodes to depart from, and navigate to. This example assumes we have already found departure
and destination
and they are location objects. options
is assumed to be null
in this example, but you can pass in the field accessible
as true
to get accessible directions.
function drawDirections(error, data) {
if(!error) {
var firstMap = getMapById(data.path[0].map);
mapView.setMap(firstMap);
mapView.removeAllPaths();
var pathOptions = {
color: 0x007afb,
radius: 12
};
mapView.drawPath(data.path, pathOptions);
}
}
departure.directionsTo(destination, options, drawDirections);
ES6 integration
npm install @mappedin/mappedin-js
The ES6 package is split into 3 modules:
mappedin-js
import * as Mappedin '@mappedin/mappedin-js';
Mappedin.test3D();...
mappedin-js/mapview3D
import MapView3D as Mappedin '@mappedin/mappedin-js/mapview3D';
new MapView3D();...
mappedin-js/mapview2D
import MapView2D as Mappedin '@mappedin/mappedin-js/mapview2D';
new MapView2D();...