-
Notifications
You must be signed in to change notification settings - Fork 109
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added support for Google road map with traffic layer by @d-m-wilson
- Loading branch information
Showing
2 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
/* | ||
* Google layer using Google Maps API | ||
* Source: https://github.com/qtrandev/LeafletTransit | ||
* Author: Quyen Tran https://github.com/qtrandev | ||
* License: https://github.com/codeforamerica/ceviche-cms/blob/master/LICENCE.md | ||
*/ | ||
|
||
/* global google: true */ | ||
|
||
L.GoogleTraffic = L.Class.extend({ | ||
includes: L.Mixin.Events, | ||
|
||
options: { | ||
minZoom: 0, | ||
maxZoom: 18, | ||
tileSize: 256, | ||
subdomains: 'abc', | ||
errorTileUrl: '', | ||
attribution: '', | ||
opacity: 1, | ||
continuousWorld: false, | ||
noWrap: false, | ||
mapOptions: { | ||
backgroundColor: '#dddddd' | ||
} | ||
}, | ||
|
||
// Possible types: SATELLITE, ROADMAP, HYBRID, TERRAIN | ||
initialize: function(type, options) { | ||
L.Util.setOptions(this, options); | ||
|
||
this._ready = google.maps.Map !== undefined; | ||
if (!this._ready) L.GoogleTraffic.asyncWait.push(this); | ||
|
||
this._type = type || 'ROADMAP'; | ||
}, | ||
|
||
onAdd: function(map, insertAtTheBottom) { | ||
this._map = map; | ||
this._insertAtTheBottom = insertAtTheBottom; | ||
|
||
// create a container div for tiles | ||
this._initContainer(); | ||
this._initMapObject(); | ||
|
||
// set up events | ||
map.on('viewreset', this._resetCallback, this); | ||
|
||
this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this); | ||
map.on('move', this._update, this); | ||
|
||
map.on('zoomanim', this._handleZoomAnim, this); | ||
|
||
//20px instead of 1em to avoid a slight overlap with google's attribution | ||
map._controlCorners.bottomright.style.marginBottom = '20px'; | ||
|
||
this._reset(); | ||
this._update(); | ||
}, | ||
|
||
onRemove: function(map) { | ||
map._container.removeChild(this._container); | ||
|
||
map.off('viewreset', this._resetCallback, this); | ||
|
||
map.off('move', this._update, this); | ||
|
||
map.off('zoomanim', this._handleZoomAnim, this); | ||
|
||
map._controlCorners.bottomright.style.marginBottom = '0em'; | ||
}, | ||
|
||
getAttribution: function() { | ||
return this.options.attribution; | ||
}, | ||
|
||
setOpacity: function(opacity) { | ||
this.options.opacity = opacity; | ||
if (opacity < 1) { | ||
L.DomUtil.setOpacity(this._container, opacity); | ||
} | ||
}, | ||
|
||
setElementSize: function(e, size) { | ||
e.style.width = size.x + 'px'; | ||
e.style.height = size.y + 'px'; | ||
}, | ||
|
||
_initContainer: function() { | ||
var tilePane = this._map._container, | ||
first = tilePane.firstChild; | ||
|
||
if (!this._container) { | ||
this._container = L.DomUtil.create('div', 'leaflet-google-layer leaflet-top leaflet-left'); | ||
this._container.id = '_GMapContainer_' + L.Util.stamp(this); | ||
this._container.style.zIndex = 'auto'; | ||
} | ||
|
||
tilePane.insertBefore(this._container, first); | ||
|
||
this.setOpacity(this.options.opacity); | ||
this.setElementSize(this._container, this._map.getSize()); | ||
}, | ||
|
||
_initMapObject: function() { | ||
if (!this._ready) return; | ||
this._google_center = new google.maps.LatLng(0, 0); | ||
var map = new google.maps.Map(this._container, { | ||
center: this._google_center, | ||
zoom: 0, | ||
tilt: 0, | ||
mapTypeId: google.maps.MapTypeId[this._type], | ||
disableDefaultUI: true, | ||
keyboardShortcuts: false, | ||
draggable: false, | ||
disableDoubleClickZoom: true, | ||
scrollwheel: false, | ||
streetViewControl: false, | ||
styles: this.options.mapOptions.styles, | ||
backgroundColor: this.options.mapOptions.backgroundColor | ||
}); | ||
var trafficLayer = new google.maps.TrafficLayer(); | ||
trafficLayer.setMap(map); | ||
|
||
var _this = this; | ||
this._reposition = google.maps.event.addListenerOnce(map, 'center_changed', | ||
function() { _this.onReposition(); }); | ||
this._google = map; | ||
|
||
google.maps.event.addListenerOnce(map, 'idle', | ||
function() { _this._checkZoomLevels(); }); | ||
//Reporting that map-object was initialized. | ||
this.fire('MapObjectInitialized', { mapObject: map }); | ||
}, | ||
|
||
_checkZoomLevels: function() { | ||
//setting the zoom level on the Google map may result in a different zoom level than the one requested | ||
//(it won't go beyond the level for which they have data). | ||
// verify and make sure the zoom levels on both Leaflet and Google maps are consistent | ||
if (this._google.getZoom() !== this._map.getZoom()) { | ||
//zoom levels are out of sync. Set the leaflet zoom level to match the google one | ||
this._map.setZoom( this._google.getZoom() ); | ||
} | ||
}, | ||
|
||
_resetCallback: function(e) { | ||
this._reset(e.hard); | ||
}, | ||
|
||
_reset: function(clearOldContainer) { | ||
this._initContainer(); | ||
}, | ||
|
||
_update: function(e) { | ||
if (!this._google) return; | ||
this._resize(); | ||
|
||
var center = this._map.getCenter(); | ||
var _center = new google.maps.LatLng(center.lat, center.lng); | ||
|
||
this._google.setCenter(_center); | ||
this._google.setZoom(Math.round(this._map.getZoom())); | ||
|
||
this._checkZoomLevels(); | ||
}, | ||
|
||
_resize: function() { | ||
var size = this._map.getSize(); | ||
if (this._container.style.width === size.x && | ||
this._container.style.height === size.y) | ||
return; | ||
this.setElementSize(this._container, size); | ||
this.onReposition(); | ||
}, | ||
|
||
|
||
_handleZoomAnim: function (e) { | ||
var center = e.center; | ||
var _center = new google.maps.LatLng(center.lat, center.lng); | ||
|
||
this._google.setCenter(_center); | ||
this._google.setZoom(Math.round(e.zoom)); | ||
}, | ||
|
||
|
||
onReposition: function() { | ||
if (!this._google) return; | ||
google.maps.event.trigger(this._google, 'resize'); | ||
} | ||
}); | ||
|
||
L.GoogleTraffic.asyncWait = []; | ||
L.GoogleTraffic.asyncInitialize = function() { | ||
var i; | ||
for (i = 0; i < L.GoogleTraffic.asyncWait.length; i++) { | ||
var o = L.GoogleTraffic.asyncWait[i]; | ||
o._ready = true; | ||
if (o._container) { | ||
o._initMapObject(); | ||
o._update(); | ||
} | ||
} | ||
L.GoogleTraffic.asyncWait = []; | ||
}; |