Repository URL to install this package:
|
Version:
0.4.0 ▾
|
// Mappyland
// Mini-lib to generate a Google Map (API v3) with markers
// Author: Matthew Cowie for Neoteric Design
// www.neotericdesign.com
function initMappyland(selector) {
const exec = function () { createMappylands(selector) }
var readyEvent = 'DOMContentLoaded'
if (typeof (Turbolinks) !== 'undefined') { readyEvent = 'turbolinks:load' }
document.addEventListener(readyEvent, exec)
try { exec.call() } catch { }
}
function createMappylands(selector) {
if (typeof (selector) === 'undefined') { selector = '[data-mappyland]' }
document.querySelectorAll(selector).forEach(function (mapContainer) {
mapContainer.mappyland = new Mappyland(mapContainer)
})
}
const Mappyland = function (container) {
if (typeof (google) === 'undefined') {
console.log("Mappyland: This page doesn't seem to have the Google Maps API embedded :(")
return false
}
this.container = container
this.settings = this.loadSettings(container)
this.gmap = new google.maps.Map(container, this.settings.gmap)
this.markers = {}
this.currentInfowindow = new google.maps.InfoWindow()
this.markerBounds = new google.maps.LatLngBounds()
this.setupSpider()
this.placeMarkers(this.parseMarkerData())
this.setupClusters()
if (!this.settings.gmap.center) { this.centerOnMarker() }
if (!this.settings.gmap.zoom) {
this.gmap.setZoom(this.settings.gmap.maxZoom || 10)
}
if (this.settings.autofitToMarkers) { this.fitToMarkers() }
}
Mappyland.settingNames = ['autoFitToMarkers', 'defaultIcon', 'gmap']
Mappyland.defaultSettings = { autoFitToMarkers: true }
Mappyland.prototype.loadSettings = function (element) {
var settings = {}
Mappyland.settingNames.forEach(function (setting) {
rawValue = element.dataset[setting]
if (typeof (rawValue) === 'undefined') {
settings[setting] = Mappyland.defaultSettings[setting]
} else {
try {
settings[setting] = JSON.parse(rawValue)
} catch {
settings[setting] = rawValue
}
}
})
return settings
}
Mappyland.prototype.findMarker = function (id) {
return this.markers[id]
}
Mappyland.prototype.triggerMarkerClick = function (idOrMarker) {
if (typeof (idOrMarker) === 'object') {
marker = idOrMarker
} else {
marker = this.findMarker(idOrMarker)
}
google.maps.event.trigger(marker, 'click')
}
Mappyland.prototype.centerOnMarker = function (marker) {
if (!marker) { marker = Object.values(this.markers)[0] }
if (!marker) { return false }
this.gmap.setCenter(marker.position)
}
Mappyland.prototype.placeMarkers = function (markerDataSet) {
for (var idx in markerDataSet) {
this.createMarker(markerDataSet[idx])
}
}
Mappyland.prototype.fitToMarkers = function () {
if (this.markerBounds.isEmpty()) { return false }
this.gmap.fitBounds(this.markerBounds)
}
Mappyland.prototype.createMarker = function (markerData) {
var coord = new google.maps.LatLng(markerData.latitude, markerData.longitude)
this.markerBounds.extend(coord)
var marker = new google.maps.Marker({
map: this.gmap,
position: coord,
title: markerData.title,
icon: (markerData.icon || this.settings.defaultIcon)
})
if (typeof (this.spider) !== 'undefined') {
this.spider.addMarker(marker)
}
this.markers[markerData.id] = marker
var infoWindowData = markerData.info_window
if (infoWindowData) {
if (typeof (infoWindowData) === 'string') {
infoWindowData = { content: infoWindowData }
}
var infowindow = new google.maps.InfoWindow(infoWindowData)
google.maps.event.addListener(marker, 'click', function () {
this.openInfoWindow(marker, infowindow)
}.bind(this))
}
return marker
}
Mappyland.prototype.openInfoWindow = function (anchor, infowindow) {
this.closeInfoWindow()
this.currentInfowindow = infowindow
infowindow.open(this.gmap, anchor)
}
Mappyland.prototype.closeInfoWindow = function () {
this.currentInfowindow.close()
}
Mappyland.prototype.parseMarkerData = function () {
data = JSON.parse(this.container.dataset.markers)
if (!Array.isArray(data)) {
// Accept JSON array behind a root key
if (Object.keys(data).length == 1) {
data = data[Object.keys(data)[0]]
} else { // Otherwise assume it's a singular marker, wrap in array
data = [data]
}
}
return data
}
Mappyland.prototype.setupClusters = function () {
if (typeof (MarkerClusterer) === 'undefined') { return false }
this.clustered = new MarkerClusterer(this.gmap, this.markers)
this.clustered.setMaxZoom(14)
}
Mappyland.prototype.setupSpider = function () {
if (typeof (OverlappingMarkerSpiderfier) === 'undefined') { return false }
this.spider = new OverlappingMarkerSpiderfier(this.gmap)
}