JavaScript API for Map Widget
Background
The Map plugin’s purpose is to provide a visualisation of where content is happening.
This adds value when the location of content is as important as the content itself.
- The Mapping Widget overlays geo-filtered content as Pins on a map;
- The user sets the initial viewing area
- The user can choose from various mapping providers – Google Maps, Mapzen, CartoDB and OpenStreetMap
- They can customise the appearance of the Map based on which provider they choose
- Each Pin reflects a Tile or a cluster (group) of Tiles
- The Pin size is relative to the cluster size. The bigger the Pin, the more content that it represents.
- The user can zoom in and out on the the map to see a more refined location of the Pins
Geohash
Tiles in the Maps Widget are grouped into clusters using geohash. Geohash is a string representation of coordinates.
Geohash is a geocoding system invented by Gustavo Niemeyer and placed into the public domain. It is a
hierarchical spatial data structure which subdivides space into buckets of grid shape, which is one of the many
applications of what is known as a Z-order curve, and generally space-filling curves.
Reference Wikipedia: Geohash
Execution flows
Map widget creation
- MapWidget is created.
var widget = new MapWidget()
- Custom JS code is executed
// custom javascript
-
Widget is initialized.
widget.initialize()
- Leaflet map is created.
var map = widget.createMap()
- Map layer is created.
map.setLayer(widget.createLayer())
- Leaflet map is created.
On map move
-
On move end is called.
widget.handleMoveEnd()
- Get all tile summaries for the current visible area.
var summaries = widget.getAggregatedDataByBounds()
- Render the fetched summaries.
widget.renderSummaries(summaries)
- Get all tile summaries for the current visible area.
On marker clicked
- On marker click is called.
widget.handleMarkerClick()
Methods
.initialize(options)
Initialize the map widget.
Parameters
Name | Type | Description |
---|---|---|
options | Object |
Options |
Return
Promise
A promise that resolves when initialization completes.
.createMap()
Creates a Leaflet Map object.
Return
L.Map
The created map object.
.createLayer(style)
Creates a Leaflet Map object.
Parameters
Name | Type | Description |
---|---|---|
style | Object |
Style object |
Return
L.Layer
The created map object.
.handleMarkerClick(event)
Handles marker click. The default implementation is updates the content list if it is connected to a
content widget. Otherwise, it only emits the ‘marker:click’ event which can be listen using .on
Parameters
Name | Type | Description |
---|---|---|
event | Event |
Click event |
Return
void
Example usage
widget.handleMarkerClick = function (event) {
var $dom = $(event.originalEvent.target);
// do something
// call parent method (optional)
Widget.prototype.handleMarkerClick.call(widget, event);
};
.handleMoveEnd()
Handles map panning, resizing and zooming.
Return
void
.createMarkerBySummary(summary)
Creates a Leaflet Map object.
Parameters
Name | Type | Description |
---|---|---|
summary |
|
Summary object |
Return
L.Marker
The marker object.
.on(eventName, handler)
Listens to an event.
Parameters
Name | Type | Description |
---|---|---|
eventName | String |
Event name |
handler | Function(data:Object):void |
A handler function |
Return
MapWidget
The current map widget object.
Example usage
// Event 'marker:click' might not emit if handleMoveEnd() or handleMarkerClick() is overrode.
widget.on('marker:click', function (summary) {
console.log('Geohash: ' + summary.geohash);
console.log('Quantity: ' + summary.quantity);
console.log('Average longitude: ' + summary.avg_location.longitude);
console.log('Average latitude: ' + summary.avg_location.latitude);
});
.getAggregatedDataByBounds(sw, ne, numGeohashPerView)
Listens to an event.
Parameters
Name | Type | Description |
---|---|---|
sw | {lat:Float, lng:Float} |
South west coordinates |
ne | {lat:Float, lng:Float} |
North east coordinates |
numGeohashPerView | Integer |
(Optional) Max number of geohashes to generate in the given view. Default: 32 |
Return
Promise<Summary[]>
A promise that resolves to summaries.
Exported methods
Exported methods can be called in parent window.
.getAggregatedDataByBounds(sw, ne, numGeohashPerView)
See .getAggregatedDataByBounds(sw, ne, numGeohashPerView)
Example usage (own Google Maps)
var map; // Google Map instance
// get the map widget by ID
var mapWidget = Stackla.WidgetManager.getWidgetInstanceByWidgetId(1234);
map.addListener('bounds_changed', function () {
var bounds = map.getBounds();
var sw = bounds.getSouthWest();
var ne = bounds.getNorthEast();
mapWidget.getAggregatedDataByBounds(
{lat: sw.lat(), lng: sw.lng()},
{lat: ne.lat(), lng: ne.lng()},
16
).then(function (summaries) {
}).catch(function (ex) {
console.error(ex);
});
});
Customization examples
Add logic before/after map widget starts.
It is possible to add logic before and after the widget initializes. Below is an example using Promise.
widget.initialize = function (options) {
(new Promise(function (resolve, reject) {
try {
// perform necessary options before widget initialization starts.
// ...
// ...
// at the end, call resolve()
resolve();
} catch (ex) {
reject(ex);
}
}).then(function () {
return MapWidget.prototype.initialize.call(widget, options);
}).then(function () {
// then perform actions after widget initialization is completed.
}).catch(function (ex) {
// catch error/exception
console.error(ex);
});
};
Initialize Leaflet with custom options
// Leaflet options @see http://leafletjs.com/reference-1.0.0.html#map-factory
widget.createMap = function () {
var map = L.map('map', {
maxBounds: [
[-85.0, -180.0],
[85.0, 180.0]
],
scrollWheelZoom: false
});
return map;
};
Use a different map layer (e.g. Google Maps)
// You can create your own Google Map style here https://mapstyle.withgoogle.com/
widget.createLayer = function (style) {
return L.gridLayer.googleMutant({
styles: styles,
type: 'roadmap'
});
};