Newer
Older
* Drupal to Google Maps API bridge.
*/
/*global jQuery, Drupal, GLatLng, GSmallZoomControl, GLargeMapControl, GMap2 */
/*global GMapTypeControl, GSmallMapControl, G_HYBRID_MAP, G_NORMAL_MAP */
/*global G_PHYSICAL_MAP, G_SATELLITE_MAP, GHierarchicalMapTypeControl */
/*global GKeyboardHandler, GLatLngBounds, GMenuMapTypeControl, GEvent */
/*global GOverviewMapControl, GScaleControl, GUnload */
(function () { // BEGIN closure
var handlers = {};
var maps = {};
var ajaxoffset = 0;
/**
* Retrieve a map object for use by a non-widget.
* Use this if you need to be able to fire events against a certain map
* which you have the mapid for.
* Be a good GMap citizen! Remember to send change()s after modifying variables!
*/
getMap: function (mapid) {
if (maps[mapid]) {
return maps[mapid];
}
else {
// Perhaps the user passed a widget id instead?
mapid = mapid.split('-').slice(1, -1).join('-');
if (maps[mapid]) {
return maps[mapid];
}
}
return false;
unloadMap: function (mapid) {
delete maps[mapid];
},
addHandler: function (handler, callback) {
if (!handlers[handler]) {
handlers[handler] = [];
handlers[handler].push(callback);
},
globalChange: function (name, userdata) {
for (var mapid in Drupal.settings.gmap) {
if (Drupal.settings.gmap.hasOwnProperty(mapid)) {
Brandon Bergren
committed
// Skip maps that are set up but not shown, etc.
if (maps[mapid]) {
maps[mapid].change(name, -1, userdata);
}
setup: function (settings) {
var obj = this;
var initcallback = function (mapid) {
return (function () {
maps[mapid].change("bootstrap_options", -1);
maps[mapid].change("boot", -1);
maps[mapid].change("init", -1);
// Send some changed events to fire up the rest of the initial settings..
maps[mapid].change("maptypechange", -1);
maps[mapid].change("controltypechange", -1);
maps[mapid].change("alignchange", -1);
// Set ready to put the event system into action.
maps[mapid].ready = true;
maps[mapid].change("ready", -1);
});
};
if (settings || (Drupal.settings && Drupal.settings.gmap)) {
var mapid = obj.id.split('-');
if (Drupal.settings['gmap_remap_widgets']) {
if (Drupal.settings['gmap_remap_widgets'][obj.id]) {
jQuery.each(Drupal.settings['gmap_remap_widgets'][obj.id].classes, function() {
jQuery(obj).addClass(this);
});
mapid = Drupal.settings['gmap_remap_widgets'][obj.id].id.split('-');
}
}
var instanceid = mapid.pop();
mapid.shift();
mapid = mapid.join('-');
var control = instanceid.replace(/\d+$/, '');
// Lazy init the map object.
if (!maps[mapid]) {
if (settings) {
maps[mapid] = new Drupal.gmap.map(settings);
}
else {
maps[mapid] = new Drupal.gmap.map(Drupal.settings.gmap[mapid]);
}
// Prepare the initialization callback.
var callback = initcallback(mapid);
setTimeout(callback, 0);
}
if (handlers[control]) {
for (var i = 0; i < handlers[control].length; i++) {
handlers[control][i].call(maps[mapid], obj);
}
}
else {
// Element with wrong class?
jQuery.fn.createGMap = function (settings, mapid) {
return this.each(function () {
if (!mapid) {
mapid = 'auto' + ajaxoffset + 'ajax';
ajaxoffset++;
}
settings.id = mapid;
.attr('id', 'gmap-' + mapid + '-gmap0')
.css('width', settings.width)
.css('height', settings.height)
.addClass('gmap-control')
.addClass('gmap-gmap')
.addClass('gmap')
.addClass('gmap-map')
.addClass('gmap-' + mapid + '-gmap')
.addClass('gmap-processed')
.each(function() {Drupal.gmap.setup.call(this, settings)});
});
};
this.vars = v;
this.map = undefined;
this.ready = false;
var _bindings = {};
/**
* Register interest in a change.
*/
if (!_bindings[name]) {
_bindings[name] = [];
}
return _bindings[name].push(callback) - 1;
};
/**
* Change notification.
* Interested parties can act on changes.
*/
var c;
if (_bindings[name]) {
for (c = 0; c < _bindings[name].length; c++) {
if (c !== id) {
_bindings[name][c](userdata);
}
}
}
if (name !== 'all') {
}
};
/**
* Deferred change notification.
* This will cause a change notification to be tacked on to the *end* of the event queue.
*/
var obj = this;
// This will move the function call to the end of the event loop.
setTimeout(function () {
obj.change(name, id, userdata);
this.getMapTypeName = function(type) {
if (type == 'map' || type == 'roadmap') return 'Map';
if (type == 'hybrid') return 'Hybrid';
if (type == 'physical' || type == 'terrain') return 'Physical';
if (type == 'satellite') return 'Satellite';
};
this.getMapTypeId = function(type) {
if (type == 'Map' || type == 'Roadmap') return google.maps.MapTypeId.ROADMAP;
if (type == 'Hybrid') return google.maps.MapTypeId.HYBRID;
if (type == 'Physical' || type == 'Terrain') return google.maps.MapTypeId.TERRAIN;
if (type == 'Satellite') return google.maps.MapTypeId.SATELLITE;
};
};
////////////////////////////////////////
// Map widget //
////////////////////////////////////////
var obj = this;
var _ib = {};
// Respond to incoming zooms
_ib.zoom = obj.bind("zoom", function (zoom) {
obj.map.setZoom(obj.vars.zoom);
});
// Respond to incoming moves
obj.map.panTo(new google.maps.LatLng(obj.vars.latitude, obj.vars.longitude));
});
// Respond to incoming width changes.
obj.map.getDiv().style.width = w;
google.maps.event.trigger(obj.map);
});
// Send out outgoing width changes.
// N/A
// Respond to incoming height changes.
_ib.height = obj.bind("heightchange", function (h) {
obj.map.getDiv().style.height = h;
google.maps.event.trigger(obj.map);
});
// Send out outgoing height changes.
// N/A
// Respond to incoming control type changes.
_ib.ctc = obj.bind("controltypechange", function () {
if (obj.vars.controltype === 'Small') {
obj.map.setOptions({navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL}});
else if (obj.vars.controltype === 'Large') {
obj.map.setOptions({navigationControlOptions: {style: google.maps.NavigationControlStyle.ZOOM_PAN}});
}
else if (obj.vars.controltype === 'Android') {
obj.map.setOptions({navigationControlOptions: {style: google.maps.NavigationControlStyle.ANDROID}});
});
// Send out outgoing control type changes.
// N/A
// Respond to incoming map type changes.
_ib.mtc = obj.bind("maptypechange", function () {
obj.map.setMapTypeId(obj.getMapTypeId(obj.vars.maptype));
});
// Send out outgoing map type changes.
// N/A
var opts = {}; // Object literal google.maps.MapOptions
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
// Disable default UI for custom options
opts.disableDefaultUI = true;
// Set draggable property
if (obj.vars.behavior.nodrag) {
opts.draggable = false;
}
else if (obj.vars.behavior.nokeyboard) {
opts.keyboardShortcuts = false;
}
// Set default map type (set to road map if nothing selected)
switch (obj.vars.maptype) {
case 'Hybrid':
opts.mapTypeId = google.maps.MapTypeId.HYBRID;
break;
case 'Physical':
opts.mapTypeId = google.maps.MapTypeId.TERRAIN;
break;
case 'Satellite':
opts.mapTypeId = google.maps.MapTypeId.SATELLITE;
break;
case 'Map':
default:
opts.mapTypeId = google.maps.MapTypeId.ROADMAP;
break;
}
opts.mapTypeIds = [];
if (obj.vars.baselayers.Map) {
opts.mapTypeIds.push(google.maps.MapTypeId.ROADMAP);
if (obj.vars.baselayers.Hybrid) {
opts.mapTypeIds.push(google.maps.MapTypeId.HYBRID);
if (obj.vars.baselayers.Physical) {
opts.mapTypeIds.push(google.maps.MapTypeId.TERRAIN);
if (obj.vars.baselayers.Satellite) {
opts.mapTypeIds.push(google.maps.MapTypeId.SATELLITE);
}
Brandon Bergren
committed
if (obj.vars.draggableCursor) {
opts.draggableCursor = obj.vars.draggableCursor;
}
if (obj.vars.draggingCursor) {
opts.draggingCursor = obj.vars.draggingCursor;
}
if (obj.vars.backgroundColor) {
opts.backgroundColor = obj.vars.backgroundColor;
}
opts.mapTypeControl = true;
opts.mapTypeControlOptions = {};
if (obj.vars.mtc === 'standard') {
opts.mapTypeControlOptions.style = google.maps.MapTypeControlStyle.DEFAULT;
else if (obj.vars.mtc === 'horiz') {
opts.mapTypeControlOptions.style = google.maps.MapTypeControlStyle.HORIZONTAL_BAR;
else if (obj.vars.mtc === 'menu') {
opts.mapTypeControlOptions.style = google.maps.MapTypeControlStyle.DROPDOWN_MENU;
// Navigation control type
if (obj.vars.controltype !== 'None') {
opts.navigationControl = true;
if (obj.vars.controltype === 'Small') {
opts.navigationControlOptions = {style: google.maps.NavigationControlStyle.SMALL};
else if (obj.vars.controltype === 'Large') {
opts.navigationControlOptions = {style: google.maps.NavigationControlStyle.ZOOM_PAN};
// Set scale control visibility
opts.scaleControl = obj.vars.behavior.scale;
// Scroll wheel control
if (obj.vars.behavior.nomousezoom) {
opts.scrollwheel = false;
// Disable double-click zoom
if (obj.vars.behavior.nocontzoom) {
opts.disableDoubleClickZoom = true;
});
obj.bind("boot", function () {
obj.map = new google.maps.Map(elem, obj.opts);
//console.log(obj.map);
});
obj.bind("init", function () {
var map = obj.map;
// Not implemented in API v3
// if (obj.vars.behavior.overview) {
// map.addControl(new GOverviewMapControl());
// }
// if (obj.vars.behavior.googlebar) {
// map.enableGoogleBar();
// }
if (obj.vars.extent) {
var c = obj.vars.extent;
var extent = new google.maps.LatLngBounds(new google.maps.LatLng(c[0][0], c[0][1]), new google.maps.LatLng(c[1][0], c[1][1]));
obj.vars.latitude = extent.getCenter().lat();
obj.vars.longitude = extent.getCenter().lng();
obj.vars.zoom = map.getBoundsZoomLevel(extent);
}
if (obj.vars.behavior.collapsehack) {
// Modify collapsable fieldsets to make maps check dom state when the resize handle
// is clicked. This may not necessarily be the correct thing to do in all themes,
// hence it being a behavior.
google.maps.event.trigger(map);
map.setCenter(new google.maps.LatLng(obj.vars.latitude, obj.vars.longitude), obj.vars.zoom);
jQuery(elem).parents('fieldset.collapsible').children('legend').children('a').click(r);
http://druler.com
committed
jQuery('.vertical-tab-button', jQuery(elem).parents('.vertical-tabs')).children('a').click(r);
jQuery(window).bind('hashchange', r);
// Would be nice, but doesn't work.
//$(elem).parents('fieldset.collapsible').children('.fieldset-wrapper').scroll(r);
map.setCenter(new google.maps.LatLng(obj.vars.latitude, obj.vars.longitude));
map.setZoom(obj.vars.zoom);
google.maps.event.addListener(map, "zoom_changed", function () {
obj.vars.zoom = map.getZoom();
obj.change("zoom", _ib.zoom);
});
// Send out outgoing moves
google.maps.event.addListener(map, "center_changed", function () {
var coord = map.getCenter();
obj.vars.latitude = coord.lat();
obj.vars.longitude = coord.lng();
obj.change("move", _ib.move);
});
// Send out outgoing map type changes.
google.maps.event.addListener(map, "maptypeid_changed", function () {
// If the map isn't ready yet, ignore it.
if (obj.ready) {
obj.vars.maptype = obj.getMapTypeName(map.getMapTypeId());
obj.change("maptypechange", _ib.mtc);
}
});
/*
google.maps.event.addListener(map, 'click', function(event) {
alert(Drupal.gmap.getIcon("big blue", 0));
var marker = new google.maps.Marker({
position: event.latLng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
marker.setMap(null);
});
});
*/
});
});
////////////////////////////////////////
// Zoom widget //
////////////////////////////////////////
var obj = this;
// Respond to incoming zooms
elem.value = obj.vars.zoom;
});
// Send out outgoing zooms
jQuery(elem).change(function () {
obj.vars.zoom = parseInt(elem.value, 10);
obj.change("zoom", binding);
});
});
////////////////////////////////////////
// Latitude widget //
////////////////////////////////////////
Drupal.gmap.addHandler('latitude', function (elem) {
// var obj = this;
// // Respond to incoming movements.
// var binding = obj.bind("move", function () {
// elem.value = '' + obj.vars.latitude;
// });
// // Send out outgoing movements.
// $(elem).change(function () {
// obj.vars.latitude = Number(this.value);
// obj.change("move", binding);
// });
});
////////////////////////////////////////
// Longitude widget //
////////////////////////////////////////
Drupal.gmap.addHandler('longitude', function (elem) {
// var obj = this;
// // Respond to incoming movements.
// var binding = obj.bind("move", function () {
// elem.value = '' + obj.vars.longitude;
// });
// // Send out outgoing movements.
// $(elem).change(function () {
// obj.vars.longitude = Number(this.value);
// obj.change("move", binding);
// });
});
////////////////////////////////////////
// Latlon widget //
////////////////////////////////////////
var obj = this;
// Respond to incoming movements.
elem.value = '' + obj.vars.latitude + ',' + obj.vars.longitude;
});
// Send out outgoing movements.
jQuery(elem).change(function () {
var t = this.value.split(',');
obj.vars.latitude = Number(t[0]);
obj.vars.longitude = Number(t[1]);
obj.change("move", binding);
});
});
////////////////////////////////////////
// Maptype widget //
////////////////////////////////////////
var obj = this;
// Respond to incoming movements.
var binding = obj.bind("maptypechange", function () {
elem.value = obj.vars.maptype;
});
// Send out outgoing movements.
jQuery(elem).change(function () {
obj.vars.maptype = elem.value;
obj.change("maptypechange", binding);
});
});
var re = /([0-9.]+)\s*(em|ex|px|in|cm|mm|pt|pc|%)/;
var ar;
if ((ar = re.exec(str.toLowerCase()))) {
return ar[1] + ar[2];
}
return null;
};
////////////////////////////////////////
// Width widget //
////////////////////////////////////////
Drupal.gmap.addHandler('width', function (elem) {
var obj = this;
// Respond to incoming width changes.
var binding = obj.bind("widthchange", function (w) {
elem.value = normalize(w);
});
// Send out outgoing width changes.
jQuery(elem).change(function () {
var n;
if ((n = normalize(elem.value))) {
elem.value = n;
obj.change('widthchange', binding, n);
}
});
obj.bind('init', function () {
////////////////////////////////////////
// Height widget //
////////////////////////////////////////
Drupal.gmap.addHandler('height', function (elem) {
var obj = this;
// Respond to incoming height changes.
var binding = obj.bind("heightchange", function (h) {
elem.value = normalize(h);
});
// Send out outgoing height changes.
jQuery(elem).change(function () {
var n;
if ((n = normalize(elem.value))) {
elem.value = n;
obj.change('heightchange', binding, n);
}
});
obj.bind('init', function () {
});
})(); // END CLOSURE
////////////////////////////////////////
// Control type widget //
////////////////////////////////////////
Drupal.gmap.addHandler('controltype', function (elem) {
var obj = this;
// Respond to incoming height changes.
var binding = obj.bind("controltypechange", function () {
elem.value = obj.vars.controltype;
});
// Send out outgoing height changes.
jQuery(elem).change(function () {
obj.vars.controltype = elem.value
obj.change("controltypechange", binding);
});
});
// // Map cleanup.
// if (Drupal.jsEnabled) {
// $(document).unload(GUnload);
// }
Drupal.behaviors.GMap = {
attach: function (context, settings) {
if (Drupal.settings && Drupal.settings['gmap_remap_widgets']) {
jQuery.each(Drupal.settings['gmap_remap_widgets'], function(key, val) {
jQuery('#'+ key).addClass('gmap-control');
jQuery('.gmap-gmap:not(.gmap-processed)', context).addClass('gmap-processed').each(function () {Drupal.gmap.setup.call(this)});
jQuery('.gmap-control:not(.gmap-processed)', context).addClass('gmap-processed').each(function () {Drupal.gmap.setup.call(this)});
http://druler.com
committed
},
detach: function (context, settings) {
jQuery('.gmap-processed', context).each(function (element) {
//find mapid
var id = jQuery(this).attr('id');
var mapid = id.split('-', 2);
//unload map
Drupal.gmap.unloadMap(mapid[1]);
});