Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
mappyland / vendor / assets / javascripts / mappyland.js
Size: Mime:
// 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)
}