/* $Id: icon.js,v 1.6 2009/02/11 20:14:39 bdragon Exp $ */ /** * @file * GIcon manager for GMap. * Required for markers to operate properly. */ /*global $, Drupal, GIcon, GPoint, GSize, G_DEFAULT_ICON */ /** * Get the GIcon corresponding to a setname / sequence. * There is only one GIcon for each slot in the sequence. * The marker set wraps around when reaching the end of the sequence. * @@@ TODO: Move this directly into the preparemarker event binding. */ Drupal.gmap.getIcon = function (setname, sequence) { var othimg = ['printImage', 'mozPrintImage', 'printShadow', 'transparent']; // If no setname, return google's default icon. if (!setname) { return G_DEFAULT_ICON; } if (!this.gicons) { this.gicons = {}; } // If no sequence, synthesise one. if (!sequence) { // @TODO make this per-map. if (!this.sequences) { this.sequences = {}; } if (!this.sequences[setname]) { this.sequences[setname] = -1; } this.sequences[setname]++; sequence = this.sequences[setname]; } if (!this.gicons[setname]) { if (!Drupal.gmap.icons[setname]) { alert('Request for invalid marker set ' + setname + '!'); } this.gicons[setname] = []; var q = Drupal.gmap.icons[setname]; var p, t; for (var i = 0; i < q.sequence.length; i++) { t = new GIcon(); p = Drupal.gmap.iconpath + q.path; t.image = p + q.sequence[i].f; if (q.shadow.f !== '') { t.shadow = p + q.shadow.f; t.shadowSize = new GSize(q.shadow.w, q.shadow.h); } t.iconSize = new GSize(q.sequence[i].w, q.sequence[i].h); t.iconAnchor = new GPoint(q.anchorX, q.anchorY); t.infoWindowAnchor = new GPoint(q.infoX, q.infoY); for (var j = 0; j < othimg.length; j++) { if (q[othimg[j]] !== '') { t[othimg[j]] = p + q[othimg[j]]; } } // @@@ imageMap? this.gicons[setname][i] = t; } delete Drupal.gmap.icons[setname]; } // TODO: Random, other cycle methods. return this.gicons[setname][sequence % this.gicons[setname].length]; }; /** * JSON callback to set up the icon defs. * When doing the JSON call, the data comes back in a packed format. * We need to expand it and file it away in a more useful format. */ Drupal.gmap.iconSetup = function () { Drupal.gmap.icons = {}; var m = Drupal.gmap.icondata; var filef, filew, fileh, files; for (var path in m) { if (m.hasOwnProperty(path)) { // Reconstitute files array filef = m[path].f; filew = Drupal.gmap.expandArray(m[path].w, filef.length); fileh = Drupal.gmap.expandArray(m[path].h, filef.length); files = []; for (var i = 0; i < filef.length; i++) { files[i] = {f : filef[i], w : filew[i], h : fileh[i]}; } for (var ini in m[path].i) { if (m[path].i.hasOwnProperty(ini)) { $.extend(Drupal.gmap.icons, Drupal.gmap.expandIconDef(m[path].i[ini], path, files)); } } } } }; /** * Expand a compressed array. * This will pad arr up to len using the last value of the old array. */ Drupal.gmap.expandArray = function (arr, len) { var d = arr[0]; for (var i = 0; i < len; i++) { if (!arr[i]) { arr[i] = d; } else { d = arr[i]; } } return arr; }; /** * Expand icon definition. * This helper function is the reverse of the packer function found in * gmap_markerinfo.inc. */ Drupal.gmap.expandIconDef = function (c, path, files) { var decomp = ['key', 'name', 'sequence', 'anchorX', 'anchorY', 'infoX', 'infoY', 'shadow', 'printImage', 'mozPrintImage', 'printShadow', 'transparent']; var fallback = ['', '', [], 0, 0, 0, 0, {f: '', h: 0, w: 0}, '', '', '', '']; var imagerep = ['shadow', 'printImage', 'mozPrintImage', 'printShadow', 'transparent']; var defaults = {}; var sets = []; var i, j; // Part 1: Defaults / Markersets // Expand arrays and fill in missing ones with fallbacks for (i = 0; i < decomp.length; i++) { if (!c[0][i]) { c[0][i] = [ fallback[i] ]; } c[0][i] = Drupal.gmap.expandArray(c[0][i], c[0][0].length); } for (i = 0; i < c[0][0].length; i++) { for (j = 0; j < decomp.length; j++) { if (i === 0) { defaults[decomp[j]] = c[0][j][i]; } else { if (!sets[i - 1]) { sets[i - 1] = {}; } sets[i - 1][decomp[j]] = c[0][j][i]; } } } for (i = 0; i < sets.length; i++) { for (j = 0; j < decomp.length; j++) { if (sets[i][decomp[j]] === fallback[j]) { sets[i][decomp[j]] = defaults[decomp[j]]; } } } var icons = {}; for (i = 0; i < sets.length; i++) { var key = sets[i].key; icons[key] = sets[i]; icons[key].path = path; delete icons[key].key; delete sets[i]; for (j = 0; j < icons[key].sequence.length; j++) { icons[key].sequence[j] = files[icons[key].sequence[j]]; } for (j = 0; j < imagerep.length; j++) { if (typeof(icons[key][imagerep[j]]) === 'number') { icons[key][imagerep[j]] = files[icons[key][imagerep[j]]]; } } } return icons; }; /** * We attach ourselves if we find a map somewhere needing markers. * Note: Since we broadcast our ready event to all maps, it doesn't * matter which one we attached to! */ Drupal.gmap.addHandler('gmap', function (elem) { var obj = this; obj.bind('init', function () { // Only expand once. if (!Drupal.gmap.icons) { Drupal.gmap.iconSetup(); } }); obj.bind('ready', function () { // Compatibility event. if (Drupal.gmap.icondata) { obj.deferChange('iconsready', -1); } }); if (!obj.vars.behavior.customicons) { // Provide icons to markers. obj.bind('preparemarker', function (marker) { marker.opts.icon = Drupal.gmap.getIcon(marker.markername, marker.offset); }); } }); /* playback timings (ms): LoadShardBlock: 161.624 (3) esindex: 0.008 captures_list: 178.373 CDXLines.iter: 13.051 (3) PetaboxLoader3.datanode: 200.949 (4) exclusion.robots: 0.295 exclusion.robots.policy: 0.282 RedisCDXSource: 0.566 PetaboxLoader3.resolve: 452.86 load_resource: 519.593 */