// Create a JSON2 object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
var JSON2;
if (!JSON2) {
JSON2 = {};
}
(function () {
"use strict";
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON2 !== 'function') {
Date.prototype.toJSON2 = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
String.prototype.toJSON2 =
Number.prototype.toJSON2 =
Boolean.prototype.toJSON2 = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON2 method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON2 === 'function') {
value = value.toJSON2(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON2 numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON2 values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' : gap ?
'[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' : gap ?
'{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
'{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON2 object does not yet have a stringify method, give it one.
if (typeof JSON2.stringify !== 'function') {
JSON2.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON2 text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON2.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON2 object does not yet have a parse method, give it one.
if (typeof JSON2.parse !== 'function') {
JSON2.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON2 text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON2 patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON2 backslash pairs with '@' (a non-JSON2 character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON2 parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON2.parse');
};
}
}());
//add contains function in Array
Array.prototype.contains = function(obj) {
var i = this.length;
while (i--) {
if (this[i] === obj) {
return true;
}
}
return false;
}
Array.prototype.max = function() {
var max = parseFloat(this[0]);
var len = this.length;
for (var i = 1; i < len; i++) if (parseFloat(this[i]) > max) max = parseFloat(this[i]);
return max;
}
Array.prototype.min = function() {
var min = parseFloat(this[0]);
var len = this.length;
for (var i = 1; i < len; i++) if (parseFloat(this[i]) < min) min = parseFloat(this[i]);
return min;
}
window.net=window.net||{};
net.imapbuilder=net.imapbuilder||{};
net.imapbuilder.gmap=net.imapbuilder.gmap||{};
var map;
var markers=[];
var labels=[];
var images=[];
var polylines=[];
var polygons=[];
var rectangles=[];
var circles=[];
var routes=[];
var current_route = 0;
var route_count = 0 ;
var map_geocoder;
var markerCluster;
var crowdMarkers=[];
var crowdMarkersId=0;
var crowdMarkersData = [] ;
//information box
var gmap_locationdetails;
var modal_div;
var crowdForm_div;
var markerID;
var tempMarker;
var tempMarkerAni;
var crowdGetLocation_div;
var errorMessage_div;
var infoZIndex = 0 ;
var heatMapArr = [];
var heatMapCon_colorRatio;
var cluster_infowindow ;
var cs_title = "Add a Location" ;
var cs_loginas = "Login as" ;
var cs_address = "Address" ;
var cs_desc = "Description" ;
var cs_data = "Crowdsourced data";
var clickCircle;
(function(){
var g=net.imapbuilder.gmap; // shorten the code of the namespace object
// icon list
g.iconlist=[];
g.iconlist[1]={};
g.iconlist[1].imagew="32";
g.iconlist[1].imageh="32";
g.iconlist[1].imageox="0";
g.iconlist[1].imageoy="0";
g.iconlist[1].imageax="16";
g.iconlist[1].imageay="32";
g.iconlist[2]={};
g.iconlist[2].imagew="32";
g.iconlist[2].imageh="32";
g.iconlist[2].imageox="0";
g.iconlist[2].imageoy="0";
g.iconlist[2].imageax="16";
g.iconlist[2].imageay="32";
g.iconlist[3]={};
g.iconlist[3].imagew="32";
g.iconlist[3].imageh="32";
g.iconlist[3].imageox="0";
g.iconlist[3].imageoy="0";
g.iconlist[3].imageax="16";
g.iconlist[3].imageay="32";
g.iconlist[4]={};
g.iconlist[4].imagew="32";
g.iconlist[4].imageh="32";
g.iconlist[4].imageox="0";
g.iconlist[4].imageoy="0";
g.iconlist[4].imageax="16";
g.iconlist[4].imageay="32";
g.iconlist[5]={};
g.iconlist[5].imagew="32";
g.iconlist[5].imageh="32";
g.iconlist[5].imageox="0";
g.iconlist[5].imageoy="0";
g.iconlist[5].imageax="16";
g.iconlist[5].imageay="32";
g.iconlist[6]={};
g.iconlist[6].imagew="32";
g.iconlist[6].imageh="32";
g.iconlist[6].imageox="0";
g.iconlist[6].imageoy="0";
g.iconlist[6].imageax="16";
g.iconlist[6].imageay="32";
g.iconlist[7]={};
g.iconlist[7].imagew="32";
g.iconlist[7].imageh="32";
g.iconlist[7].imageox="0";
g.iconlist[7].imageoy="0";
g.iconlist[7].imageax="16";
g.iconlist[7].imageay="32";
g.iconlist[8]={};
g.iconlist[8].imagew="32";
g.iconlist[8].imageh="32";
g.iconlist[8].imageox="0";
g.iconlist[8].imageoy="0";
g.iconlist[8].imageax="16";
g.iconlist[8].imageay="32";
g.iconlist[9]={};
g.iconlist[9].imagew="32";
g.iconlist[9].imageh="32";
g.iconlist[9].imageox="0";
g.iconlist[9].imageoy="0";
g.iconlist[9].imageax="16";
g.iconlist[9].imageay="32";
g.iconlist[10]={};
g.iconlist[10].imagew="32";
g.iconlist[10].imageh="32";
g.iconlist[10].imageox="0";
g.iconlist[10].imageoy="0";
g.iconlist[10].imageax="16";
g.iconlist[10].imageay="32";
g.iconlist[11]={};
g.iconlist[11].imagew="32";
g.iconlist[11].imageh="32";
g.iconlist[11].imageox="0";
g.iconlist[11].imageoy="0";
g.iconlist[11].imageax="16";
g.iconlist[11].imageay="32";
g.iconlist[12]={};
g.iconlist[12].imagew="32";
g.iconlist[12].imageh="32";
g.iconlist[12].imageox="0";
g.iconlist[12].imageoy="0";
g.iconlist[12].imageax="16";
g.iconlist[12].imageay="32";
g.iconlist[13]={};
g.iconlist[13].imagew="32";
g.iconlist[13].imageh="32";
g.iconlist[13].imageox="0";
g.iconlist[13].imageoy="0";
g.iconlist[13].imageax="16";
g.iconlist[13].imageay="32";
g.iconlist[14]={};
g.iconlist[14].imagew="32";
g.iconlist[14].imageh="32";
g.iconlist[14].imageox="0";
g.iconlist[14].imageoy="0";
g.iconlist[14].imageax="16";
g.iconlist[14].imageay="32";
g.iconlist[15]={};
g.iconlist[15].imagew="32";
g.iconlist[15].imageh="32";
g.iconlist[15].imageox="0";
g.iconlist[15].imageoy="0";
g.iconlist[15].imageax="11";
g.iconlist[15].imageay="32";
g.iconlist[16]={};
g.iconlist[16].imagew="32";
g.iconlist[16].imageh="32";
g.iconlist[16].imageox="0";
g.iconlist[16].imageoy="0";
g.iconlist[16].imageax="11";
g.iconlist[16].imageay="32";
g.iconlist[17]={};
g.iconlist[17].imagew="32";
g.iconlist[17].imageh="32";
g.iconlist[17].imageox="0";
g.iconlist[17].imageoy="0";
g.iconlist[17].imageax="11";
g.iconlist[17].imageay="32";
g.iconlist[18]={};
g.iconlist[18].imagew="32";
g.iconlist[18].imageh="32";
g.iconlist[18].imageox="0";
g.iconlist[18].imageoy="0";
g.iconlist[18].imageax="11";
g.iconlist[18].imageay="32";
g.iconlist[19]={};
g.iconlist[19].imagew="32";
g.iconlist[19].imageh="32";
g.iconlist[19].imageox="0";
g.iconlist[19].imageoy="0";
g.iconlist[19].imageax="11";
g.iconlist[19].imageay="32";
g.iconlist[20]={};
g.iconlist[20].imagew="32";
g.iconlist[20].imageh="32";
g.iconlist[20].imageox="0";
g.iconlist[20].imageoy="0";
g.iconlist[20].imageax="11";
g.iconlist[20].imageay="32";
g.iconlist[21]={};
g.iconlist[21].imagew="32";
g.iconlist[21].imageh="32";
g.iconlist[21].imageox="0";
g.iconlist[21].imageoy="0";
g.iconlist[21].imageax="11";
g.iconlist[21].imageay="32";
g.iconlist[22]={};
g.iconlist[22].imagew="31";
g.iconlist[22].imageh="35";
g.iconlist[22].imageox="0";
g.iconlist[22].imageoy="0";
g.iconlist[22].imageax="15";
g.iconlist[22].imageay="34";
g.iconlist[23]={};
g.iconlist[23].imagew="31";
g.iconlist[23].imageh="35";
g.iconlist[23].imageox="0";
g.iconlist[23].imageoy="0";
g.iconlist[23].imageax="15";
g.iconlist[23].imageay="34";
g.iconlist[24]={};
g.iconlist[24].imagew="31";
g.iconlist[24].imageh="35";
g.iconlist[24].imageox="0";
g.iconlist[24].imageoy="0";
g.iconlist[24].imageax="15";
g.iconlist[24].imageay="34";
g.iconlist[25]={};
g.iconlist[25].imagew="31";
g.iconlist[25].imageh="35";
g.iconlist[25].imageox="0";
g.iconlist[25].imageoy="0";
g.iconlist[25].imageax="15";
g.iconlist[25].imageay="34";
g.iconlist[26]={};
g.iconlist[26].imagew="31";
g.iconlist[26].imageh="35";
g.iconlist[26].imageox="0";
g.iconlist[26].imageoy="0";
g.iconlist[26].imageax="15";
g.iconlist[26].imageay="34";
g.iconlist[27]={};
g.iconlist[27].imagew="31";
g.iconlist[27].imageh="35";
g.iconlist[27].imageox="0";
g.iconlist[27].imageoy="0";
g.iconlist[27].imageax="15";
g.iconlist[27].imageay="34";
g.iconlist[28]={};
g.iconlist[28].imagew="31";
g.iconlist[28].imageh="35";
g.iconlist[28].imageox="0";
g.iconlist[28].imageoy="0";
g.iconlist[28].imageax="15";
g.iconlist[28].imageay="34";
g.iconlist[29]={};
g.iconlist[29].imagew="31";
g.iconlist[29].imageh="35";
g.iconlist[29].imageox="0";
g.iconlist[29].imageoy="0";
g.iconlist[29].imageax="15";
g.iconlist[29].imageay="34";
g.iconlist[30]={};
g.iconlist[30].imagew="31";
g.iconlist[30].imageh="35";
g.iconlist[30].imageox="0";
g.iconlist[30].imageoy="0";
g.iconlist[30].imageax="15";
g.iconlist[30].imageay="34";
g.iconlist[31]={};
g.iconlist[31].imagew="31";
g.iconlist[31].imageh="35";
g.iconlist[31].imageox="0";
g.iconlist[31].imageoy="0";
g.iconlist[31].imageax="15";
g.iconlist[31].imageay="34";
g.iconlist[32]={};
g.iconlist[32].imagew="31";
g.iconlist[32].imageh="35";
g.iconlist[32].imageox="0";
g.iconlist[32].imageoy="0";
g.iconlist[32].imageax="15";
g.iconlist[32].imageay="34";
g.iconlist[33]={};
g.iconlist[33].imagew="31";
g.iconlist[33].imageh="35";
g.iconlist[33].imageox="0";
g.iconlist[33].imageoy="0";
g.iconlist[33].imageax="15";
g.iconlist[33].imageay="34";
g.iconlist[34]={};
g.iconlist[34].imagew="31";
g.iconlist[34].imageh="35";
g.iconlist[34].imageox="0";
g.iconlist[34].imageoy="0";
g.iconlist[34].imageax="15";
g.iconlist[34].imageay="34";
g.iconlist[35]={};
g.iconlist[35].imagew="31";
g.iconlist[35].imageh="35";
g.iconlist[35].imageox="0";
g.iconlist[35].imageoy="0";
g.iconlist[35].imageax="15";
g.iconlist[35].imageay="34";
g.iconlist[36]={};
g.iconlist[36].imagew="31";
g.iconlist[36].imageh="35";
g.iconlist[36].imageox="0";
g.iconlist[36].imageoy="0";
g.iconlist[36].imageax="15";
g.iconlist[36].imageay="34";
g.iconlist[37]={};
g.iconlist[37].imagew="31";
g.iconlist[37].imageh="35";
g.iconlist[37].imageox="0";
g.iconlist[37].imageoy="0";
g.iconlist[37].imageax="15";
g.iconlist[37].imageay="34";
g.iconlist[38]={};
g.iconlist[38].imagew="31";
g.iconlist[38].imageh="35";
g.iconlist[38].imageox="0";
g.iconlist[38].imageoy="0";
g.iconlist[38].imageax="15";
g.iconlist[38].imageay="34";
g.iconlist[39]={};
g.iconlist[39].imagew="31";
g.iconlist[39].imageh="35";
g.iconlist[39].imageox="0";
g.iconlist[39].imageoy="0";
g.iconlist[39].imageax="15";
g.iconlist[39].imageay="34";
g.iconlist[40]={};
g.iconlist[40].imagew="31";
g.iconlist[40].imageh="35";
g.iconlist[40].imageox="0";
g.iconlist[40].imageoy="0";
g.iconlist[40].imageax="15";
g.iconlist[40].imageay="34";
g.iconlist[41]={};
g.iconlist[41].imagew="31";
g.iconlist[41].imageh="35";
g.iconlist[41].imageox="0";
g.iconlist[41].imageoy="0";
g.iconlist[41].imageax="15";
g.iconlist[41].imageay="34";
g.iconlist[42]={};
g.iconlist[42].imagew="31";
g.iconlist[42].imageh="35";
g.iconlist[42].imageox="0";
g.iconlist[42].imageoy="0";
g.iconlist[42].imageax="15";
g.iconlist[42].imageay="34";
g.iconlist[43]={};
g.iconlist[43].imagew="31";
g.iconlist[43].imageh="35";
g.iconlist[43].imageox="0";
g.iconlist[43].imageoy="0";
g.iconlist[43].imageax="15";
g.iconlist[43].imageay="34";
g.iconlist[44]={};
g.iconlist[44].imagew="31";
g.iconlist[44].imageh="35";
g.iconlist[44].imageox="0";
g.iconlist[44].imageoy="0";
g.iconlist[44].imageax="15";
g.iconlist[44].imageay="34";
g.iconlist[45]={};
g.iconlist[45].imagew="31";
g.iconlist[45].imageh="35";
g.iconlist[45].imageox="0";
g.iconlist[45].imageoy="0";
g.iconlist[45].imageax="15";
g.iconlist[45].imageay="34";
g.iconlist[46]={};
g.iconlist[46].imagew="31";
g.iconlist[46].imageh="35";
g.iconlist[46].imageox="0";
g.iconlist[46].imageoy="0";
g.iconlist[46].imageax="15";
g.iconlist[46].imageay="34";
g.iconlist[47]={};
g.iconlist[47].imagew="31";
g.iconlist[47].imageh="35";
g.iconlist[47].imageox="0";
g.iconlist[47].imageoy="0";
g.iconlist[47].imageax="15";
g.iconlist[47].imageay="34";
g.iconlist[48]={};
g.iconlist[48].imagew="31";
g.iconlist[48].imageh="35";
g.iconlist[48].imageox="0";
g.iconlist[48].imageoy="0";
g.iconlist[48].imageax="15";
g.iconlist[48].imageay="34";
g.iconlist[49]={};
g.iconlist[49].imagew="31";
g.iconlist[49].imageh="35";
g.iconlist[49].imageox="0";
g.iconlist[49].imageoy="0";
g.iconlist[49].imageax="15";
g.iconlist[49].imageay="34";
g.iconlist[50]={};
g.iconlist[50].imagew="31";
g.iconlist[50].imageh="35";
g.iconlist[50].imageox="0";
g.iconlist[50].imageoy="0";
g.iconlist[50].imageax="15";
g.iconlist[50].imageay="34";
g.iconlist[51]={};
g.iconlist[51].imagew="31";
g.iconlist[51].imageh="35";
g.iconlist[51].imageox="0";
g.iconlist[51].imageoy="0";
g.iconlist[51].imageax="15";
g.iconlist[51].imageay="34";
g.iconlist[52]={};
g.iconlist[52].imagew="31";
g.iconlist[52].imageh="35";
g.iconlist[52].imageox="0";
g.iconlist[52].imageoy="0";
g.iconlist[52].imageax="15";
g.iconlist[52].imageay="34";
g.iconlist[53]={};
g.iconlist[53].imagew="31";
g.iconlist[53].imageh="35";
g.iconlist[53].imageox="0";
g.iconlist[53].imageoy="0";
g.iconlist[53].imageax="15";
g.iconlist[53].imageay="34";
g.iconlist[54]={};
g.iconlist[54].imagew="31";
g.iconlist[54].imageh="35";
g.iconlist[54].imageox="0";
g.iconlist[54].imageoy="0";
g.iconlist[54].imageax="15";
g.iconlist[54].imageay="34";
g.iconlist[55]={};
g.iconlist[55].imagew="31";
g.iconlist[55].imageh="35";
g.iconlist[55].imageox="0";
g.iconlist[55].imageoy="0";
g.iconlist[55].imageax="15";
g.iconlist[55].imageay="34";
g.iconlist[56]={};
g.iconlist[56].imagew="31";
g.iconlist[56].imageh="35";
g.iconlist[56].imageox="0";
g.iconlist[56].imageoy="0";
g.iconlist[56].imageax="15";
g.iconlist[56].imageay="34";
g.iconlist[57]={};
g.iconlist[57].imagew="31";
g.iconlist[57].imageh="35";
g.iconlist[57].imageox="0";
g.iconlist[57].imageoy="0";
g.iconlist[57].imageax="15";
g.iconlist[57].imageay="34";
g.iconlist[58]={};
g.iconlist[58].imagew="31";
g.iconlist[58].imageh="35";
g.iconlist[58].imageox="0";
g.iconlist[58].imageoy="0";
g.iconlist[58].imageax="15";
g.iconlist[58].imageay="34";
g.iconlist[59]={};
g.iconlist[59].imagew="31";
g.iconlist[59].imageh="35";
g.iconlist[59].imageox="0";
g.iconlist[59].imageoy="0";
g.iconlist[59].imageax="15";
g.iconlist[59].imageay="34";
g.iconlist[60]={};
g.iconlist[60].imagew="31";
g.iconlist[60].imageh="35";
g.iconlist[60].imageox="0";
g.iconlist[60].imageoy="0";
g.iconlist[60].imageax="15";
g.iconlist[60].imageay="34";
g.iconlist[61]={};
g.iconlist[61].imagew="31";
g.iconlist[61].imageh="35";
g.iconlist[61].imageox="0";
g.iconlist[61].imageoy="0";
g.iconlist[61].imageax="15";
g.iconlist[61].imageay="34";
g.iconlist[62]={};
g.iconlist[62].imagew="31";
g.iconlist[62].imageh="35";
g.iconlist[62].imageox="0";
g.iconlist[62].imageoy="0";
g.iconlist[62].imageax="15";
g.iconlist[62].imageay="34";
g.iconlist[63]={};
g.iconlist[63].imagew="31";
g.iconlist[63].imageh="35";
g.iconlist[63].imageox="0";
g.iconlist[63].imageoy="0";
g.iconlist[63].imageax="15";
g.iconlist[63].imageay="34";
g.iconlist[64]={};
g.iconlist[64].imagew="31";
g.iconlist[64].imageh="35";
g.iconlist[64].imageox="0";
g.iconlist[64].imageoy="0";
g.iconlist[64].imageax="15";
g.iconlist[64].imageay="34";
g.iconlist[65]={};
g.iconlist[65].imagew="31";
g.iconlist[65].imageh="35";
g.iconlist[65].imageox="0";
g.iconlist[65].imageoy="0";
g.iconlist[65].imageax="15";
g.iconlist[65].imageay="34";
g.iconlist[66]={};
g.iconlist[66].imagew="31";
g.iconlist[66].imageh="35";
g.iconlist[66].imageox="0";
g.iconlist[66].imageoy="0";
g.iconlist[66].imageax="15";
g.iconlist[66].imageay="34";
g.iconlist[67]={};
g.iconlist[67].imagew="31";
g.iconlist[67].imageh="35";
g.iconlist[67].imageox="0";
g.iconlist[67].imageoy="0";
g.iconlist[67].imageax="15";
g.iconlist[67].imageay="34";
g.iconlist[68]={};
g.iconlist[68].imagew="31";
g.iconlist[68].imageh="35";
g.iconlist[68].imageox="0";
g.iconlist[68].imageoy="0";
g.iconlist[68].imageax="15";
g.iconlist[68].imageay="34";
g.iconlist[69]={};
g.iconlist[69].imagew="31";
g.iconlist[69].imageh="35";
g.iconlist[69].imageox="0";
g.iconlist[69].imageoy="0";
g.iconlist[69].imageax="15";
g.iconlist[69].imageay="34";
g.iconlist[70]={};
g.iconlist[70].imagew="31";
g.iconlist[70].imageh="35";
g.iconlist[70].imageox="0";
g.iconlist[70].imageoy="0";
g.iconlist[70].imageax="15";
g.iconlist[70].imageay="34";
g.iconlist[71]={};
g.iconlist[71].imagew="31";
g.iconlist[71].imageh="35";
g.iconlist[71].imageox="0";
g.iconlist[71].imageoy="0";
g.iconlist[71].imageax="15";
g.iconlist[71].imageay="34";
g.iconlist[72]={};
g.iconlist[72].imagew="20";
g.iconlist[72].imageh="20";
g.iconlist[72].imageox="0";
g.iconlist[72].imageoy="0";
g.iconlist[72].imageax="10";
g.iconlist[72].imageay="10";
g.iconlist[73]={};
g.iconlist[73].imagew="20";
g.iconlist[73].imageh="20";
g.iconlist[73].imageox="0";
g.iconlist[73].imageoy="0";
g.iconlist[73].imageax="10";
g.iconlist[73].imageay="10";
g.iconlist[74]={};
g.iconlist[74].imagew="20";
g.iconlist[74].imageh="20";
g.iconlist[74].imageox="0";
g.iconlist[74].imageoy="0";
g.iconlist[74].imageax="10";
g.iconlist[74].imageay="10";
g.iconlist[75]={};
g.iconlist[75].imagew="12";
g.iconlist[75].imageh="12";
g.iconlist[75].imageox="0";
g.iconlist[75].imageoy="0";
g.iconlist[75].imageax="6";
g.iconlist[75].imageay="12";
g.iconlist[76]={};
g.iconlist[76].imagew="12";
g.iconlist[76].imageh="12";
g.iconlist[76].imageox="0";
g.iconlist[76].imageoy="0";
g.iconlist[76].imageax="6";
g.iconlist[76].imageay="12";
g.iconlist[77]={};
g.iconlist[77].imagew="12";
g.iconlist[77].imageh="12";
g.iconlist[77].imageox="0";
g.iconlist[77].imageoy="0";
g.iconlist[77].imageax="6";
g.iconlist[77].imageay="12";
g.iconlist[78]={};
g.iconlist[78].imagew="12";
g.iconlist[78].imageh="12";
g.iconlist[78].imageox="0";
g.iconlist[78].imageoy="0";
g.iconlist[78].imageax="6";
g.iconlist[78].imageay="12";
g.iconlist[79]={};
g.iconlist[79].imagew="12";
g.iconlist[79].imageh="12";
g.iconlist[79].imageox="0";
g.iconlist[79].imageoy="0";
g.iconlist[79].imageax="6";
g.iconlist[79].imageay="12";
g.iconlist[80]={};
g.iconlist[80].imagew="12";
g.iconlist[80].imageh="12";
g.iconlist[80].imageox="0";
g.iconlist[80].imageoy="0";
g.iconlist[80].imageax="6";
g.iconlist[80].imageay="12";
g.iconlist[81]={};
g.iconlist[81].imagew="12";
g.iconlist[81].imageh="12";
g.iconlist[81].imageox="0";
g.iconlist[81].imageoy="0";
g.iconlist[81].imageax="6";
g.iconlist[81].imageay="12";
g.iconlist[82]={};
g.iconlist[82].imagew="12";
g.iconlist[82].imageh="12";
g.iconlist[82].imageox="0";
g.iconlist[82].imageoy="0";
g.iconlist[82].imageax="6";
g.iconlist[82].imageay="12";
g.iconlist[83]={};
g.iconlist[83].imagew="12";
g.iconlist[83].imageh="12";
g.iconlist[83].imageox="0";
g.iconlist[83].imageoy="0";
g.iconlist[83].imageax="6";
g.iconlist[83].imageay="12";
g.iconlist[84]={};
g.iconlist[84].imagew="12";
g.iconlist[84].imageh="12";
g.iconlist[84].imageox="0";
g.iconlist[84].imageoy="0";
g.iconlist[84].imageax="6";
g.iconlist[84].imageay="12";
g.iconlist[85]={};
g.iconlist[85].imagew="12";
g.iconlist[85].imageh="12";
g.iconlist[85].imageox="0";
g.iconlist[85].imageoy="0";
g.iconlist[85].imageax="6";
g.iconlist[85].imageay="12";
g.iconlist[86]={};
g.iconlist[86].imagew="12";
g.iconlist[86].imageh="12";
g.iconlist[86].imageox="0";
g.iconlist[86].imageoy="0";
g.iconlist[86].imageax="6";
g.iconlist[86].imageay="12";
g.iconlist[87]={};
g.iconlist[87].imagew="31";
g.iconlist[87].imageh="35";
g.iconlist[87].imageox="0";
g.iconlist[87].imageoy="0";
g.iconlist[87].imageax="15";
g.iconlist[87].imageay="35";
g.iconlist[88]={};
g.iconlist[88].imagew="31";
g.iconlist[88].imageh="35";
g.iconlist[88].imageox="0";
g.iconlist[88].imageoy="0";
g.iconlist[88].imageax="15";
g.iconlist[88].imageay="35";
g.iconlist[89]={};
g.iconlist[89].imagew="31";
g.iconlist[89].imageh="35";
g.iconlist[89].imageox="0";
g.iconlist[89].imageoy="0";
g.iconlist[89].imageax="15";
g.iconlist[89].imageay="35";
g.iconlist[90]={};
g.iconlist[90].imagew="31";
g.iconlist[90].imageh="35";
g.iconlist[90].imageox="0";
g.iconlist[90].imageoy="0";
g.iconlist[90].imageax="15";
g.iconlist[90].imageay="35";
g.iconlist[91]={};
g.iconlist[91].imagew="31";
g.iconlist[91].imageh="35";
g.iconlist[91].imageox="0";
g.iconlist[91].imageoy="0";
g.iconlist[91].imageax="15";
g.iconlist[91].imageay="35";
g.iconlist[92]={};
g.iconlist[92].imagew="31";
g.iconlist[92].imageh="35";
g.iconlist[92].imageox="0";
g.iconlist[92].imageoy="0";
g.iconlist[92].imageax="15";
g.iconlist[92].imageay="35";
g.iconlist[93]={};
g.iconlist[93].imagew="31";
g.iconlist[93].imageh="35";
g.iconlist[93].imageox="0";
g.iconlist[93].imageoy="0";
g.iconlist[93].imageax="15";
g.iconlist[93].imageay="35";
g.iconlist[94]={};
g.iconlist[94].imagew="31";
g.iconlist[94].imageh="35";
g.iconlist[94].imageox="0";
g.iconlist[94].imageoy="0";
g.iconlist[94].imageax="15";
g.iconlist[94].imageay="35";
g.iconlist[95]={};
g.iconlist[95].imagew="31";
g.iconlist[95].imageh="35";
g.iconlist[95].imageox="0";
g.iconlist[95].imageoy="0";
g.iconlist[95].imageax="15";
g.iconlist[95].imageay="35";
g.expire=true; var limit_object = 8;
var object_count = 0 ;
var opened_window ;
var searchMarkerID = 0 ;
g.run=function(d){
g.data=JSON2.parse(d);
if( g.data.datalist == undefined){
g.data.datalist={};
g.data.datalist.position=""; // top , right, left, bottom
g.data.datalist.width=""; // none if top or bottom
g.data.datalist.height=""; // none if left or right
g.data.datalist.bgcolor="#F0F0F0";
}else{
if( g.data.datalist.position != undefined){
var positionArr=["", "top", "bottom", "left", "right"];
g.data.datalist.position=positionArr[g.data.datalist.position] ;
}
}
if(g.data.datalist.showmarkers== undefined)
g.data.datalist.showmarkers=-1;
if( g.data.crowdmap == undefined){
g.data.crowdmap={};
g.data.crowdmap.mode="";
g.data.crowdmap.markericon=3;
}
//g.data.width="800px";
//g.data.height="600px";
// modify to 100% if browser is mobile
/*
if(navigator.userAgent.indexOf('iPhone')!=-1||navigator.userAgent.indexOf('Android')!=-1){
g.data.width=100;
g.data.width_unit='%';
g.data.height=100;
g.data.height_unit='%';
}
*/
var gmap_informationbox_style="overflow: hidden; border: 1px solid #DDD; font-family: Verdana,Geneva,sans-serif; font-size: 12px; margin: 5px;";
var width = g.data.width+g.data.width_unit;
var height = g.data.height+g.data.height_unit;
if( g.data.datalist.position=="top"||g.data.datalist.position=="left" )
document.write('
'+
''+
'');
else
document.write(''+
''+
'');
var script=document.createElement('script');
var lang = '';
if(g.data.lang != undefined && g.data.lang != "")
lang = '&language='+g.data.lang;
// here we dynamically determine whether mapkey is used
script.src='//maps.google.com/maps/api/js?key='+net.imapbuilder.gmap.mapkey+'&callback=net.imapbuilder.gmap.initialize&libraries=geometry'+lang; // &v=3.3
script.type='text/javascript';
document.body.appendChild(script);
if( g.data.font_size!=undefined)
document.getElementById('gmap_'+g.data.fileid).style.fontSize=g.data.font_size+'px';
if( g.data.font_family!=undefined)
document.getElementById('gmap_'+g.data.fileid).style.fontFamily=g.data.font_family;
}
// get device width and height
g.getWidth=function(){
xWidth = null;
if(window.screen != null)
xWidth = window.screen.availWidth;
if(window.innerWidth != null)
xWidth = window.innerWidth;
if(document.body != null)
xWidth = document.body.clientWidth;
return xWidth;
}
g.getHeight=function() {
xHeight = null;
if(window.screen != null)
xHeight = window.screen.availHeight;
if(window.innerHeight != null)
xHeight = window.innerHeight;
if(document.body != null)
xHeight = document.body.clientHeight;
return xHeight;
}
g.initialize=function(){
map_geocoder=new google.maps.Geocoder();
// start of clustering function
//if(g.data.clustering===true){
function MarkerClusterer(map, opt_markers, opt_options) {
// MarkerClusterer implements google.maps.OverlayView interface. We use the
// extend function to extend MarkerClusterer with google.maps.OverlayView
// because it might not always be available when the code is defined so we
// look for it at the last possible moment. If it doesn't exist now then
// there is no point going ahead :)
this.extend(MarkerClusterer, google.maps.OverlayView);
this.map_ = map;
/**
* @type {Array.}
* @private
*/
this.markers_ = [];
/**
* @type {Array.}
*/
this.clusters_ = [];
this.sizes = [53, 56, 66, 78, 90];
/**
* @private
*/
this.styles_ = [];
/**
* @type {boolean}
* @private
*/
this.ready_ = false;
var options = opt_options || {};
/**
* @type {number}
* @private
*/
this.gridSize_ = options['gridSize'] || 60;
/**
* @private
*/
this.minClusterSize_ = options['minimumClusterSize'] || 2;
/**
* @type {?number}
* @private
*/
this.maxZoom_ = options['maxZoom'] || null;
this.styles_ = options['styles'] || [];
/**
* @type {string}
* @private
*/
this.imagePath_ = options['imagePath'] ||
this.MARKER_CLUSTER_IMAGE_PATH_;
/**
* @type {string}
* @private
*/
this.imageExtension_ = options['imageExtension'] ||
this.MARKER_CLUSTER_IMAGE_EXTENSION_;
/**
* @type {boolean}
* @private
*/
this.zoomOnClick_ = true;
if (options['zoomOnClick'] != undefined) {
this.zoomOnClick_ = options['zoomOnClick'];
}
/**
* @type {boolean}
* @private
*/
this.averageCenter_ = false;
if (options['averageCenter'] != undefined) {
this.averageCenter_ = options['averageCenter'];
}
this.setupStyles_();
this.setMap(map);
/**
* @type {number}
* @private
*/
this.prevZoom_ = this.map_.getZoom();
// Add the map event listeners
var that = this;
google.maps.event.addListener(this.map_, 'zoom_changed', function() {
var zoom = that.map_.getZoom();
if (that.prevZoom_ != zoom) {
that.prevZoom_ = zoom;
that.resetViewport();
}
});
google.maps.event.addListener(this.map_, 'idle', function() {
that.redraw();
});
// Finally, add the markers
if (opt_markers && opt_markers.length) {
this.addMarkers(opt_markers, false);
}
}
/**
* The marker cluster image path.
*
* @type {string}
* @private
*/
MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ =
'//google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/' +
'images/m';
/**
* The marker cluster image path.
*
* @type {string}
* @private
*/
MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = 'png';
/**
* Extends a objects prototype by anothers.
*
* @param {Object} obj1 The object to be extended.
* @param {Object} obj2 The object to extend with.
* @return {Object} The new extended object.
* @ignore
*/
MarkerClusterer.prototype.extend = function(obj1, obj2) {
return (function(object) {
for (var property in object.prototype) {
this.prototype[property] = object.prototype[property];
}
return this;
}).apply(obj1, [obj2]);
};
/**
* Implementaion of the interface method.
* @ignore
*/
MarkerClusterer.prototype.onAdd = function() {
this.setReady_(true);
};
/**
* Implementaion of the interface method.
* @ignore
*/
MarkerClusterer.prototype.draw = function() {};
/**
* Sets up the styles object.
*
* @private
*/
MarkerClusterer.prototype.setupStyles_ = function() {
if (this.styles_.length) {
return;
}
for (var i = 0, size; size = this.sizes[i]; i++) {
this.styles_.push({
url: this.imagePath_ + (i + 1) + '.' + this.imageExtension_,
height: size,
width: size
});
}
};
/**
* Fit the map to the bounds of the markers in the clusterer.
*/
MarkerClusterer.prototype.fitMapToMarkers = function() {
var markers = this.getMarkers();
var bounds = new google.maps.LatLngBounds();
for (var i = 0, marker; marker = markers[i]; i++) {
bounds.extend(marker.getPosition());
}
this.map_.fitBounds(bounds);
};
/**
* Sets the styles.
*
* @param {Object} styles The style to set.
*/
MarkerClusterer.prototype.setStyles = function(styles) {
this.styles_ = styles;
};
/**
* Gets the styles.
*
* @return {Object} The styles object.
*/
MarkerClusterer.prototype.getStyles = function() {
return this.styles_;
};
/**
* Whether zoom on click is set.
*
* @return {boolean} True if zoomOnClick_ is set.
*/
MarkerClusterer.prototype.isZoomOnClick = function() {
return this.zoomOnClick_;
};
/**
* Whether average center is set.
*
* @return {boolean} True if averageCenter_ is set.
*/
MarkerClusterer.prototype.isAverageCenter = function() {
return this.averageCenter_;
};
/**
* Returns the array of markers in the clusterer.
*
* @return {Array.} The markers.
*/
MarkerClusterer.prototype.getMarkers = function() {
return this.markers_;
};
/**
* Returns the number of markers in the clusterer
*
* @return {Number} The number of markers.
*/
MarkerClusterer.prototype.getTotalMarkers = function() {
return this.markers_.length;
};
/**
* Sets the max zoom for the clusterer.
*
* @param {number} maxZoom The max zoom level.
*/
MarkerClusterer.prototype.setMaxZoom = function(maxZoom) {
this.maxZoom_ = maxZoom;
};
/**
* Gets the max zoom for the clusterer.
*
* @return {number} The max zoom level.
*/
MarkerClusterer.prototype.getMaxZoom = function() {
return this.maxZoom_;
};
/**
* The function for calculating the cluster icon image.
*
* @param {Array.} markers The markers in the clusterer.
* @param {number} numStyles The number of styles available.
* @return {Object} A object properties: 'text' (string) and 'index' (number).
* @private
*/
MarkerClusterer.prototype.calculator_ = function(markers, numStyles) {
var index = 0;
var count = markers.length;
var dv = count;
while (dv !== 0) {
dv = parseInt(dv / 10, 10);
index++;
}
index = Math.min(index, numStyles);
return {
text: count,
index: index
};
};
/**
* Set the calculator function.
*
* @param {function(Array, number)} calculator The function to set as the
* calculator. The function should return a object properties:
* 'text' (string) and 'index' (number).
*
*/
MarkerClusterer.prototype.setCalculator = function(calculator) {
this.calculator_ = calculator;
};
/**
* Get the calculator function.
*
* @return {function(Array, number)} the calculator function.
*/
MarkerClusterer.prototype.getCalculator = function() {
return this.calculator_;
};
/**
* Add an array of markers to the clusterer.
*
* @param {Array.} markers The markers to add.
* @param {boolean=} opt_nodraw Whether to redraw the clusters.
*/
MarkerClusterer.prototype.addMarkers = function(markers, opt_nodraw) {
/*
for (var i = 0, marker; marker = markers[i]; i++) {
this.pushMarkerTo_(marker);
}
*/
//Terry modified 20120326
for(var i = 0 ; i < markers.length ; i++){
if( markers[i] != undefined )
this.pushMarkerTo_(markers[i]);
}
if (!opt_nodraw) {
this.redraw();
}
};
/**
* Pushes a marker to the clusterer.
*
* @param {google.maps.Marker} marker The marker to add.
* @private
*/
MarkerClusterer.prototype.pushMarkerTo_ = function(marker) {
marker.isAdded = false;
if (marker['draggable']) {
// If the marker is draggable add a listener so we update the clusters on
// the drag end.
var that = this;
google.maps.event.addListener(marker, 'dragend', function() {
marker.isAdded = false;
that.repaint();
});
}
this.markers_.push(marker);
};
/**
* Adds a marker to the clusterer and redraws if needed.
*
* @param {google.maps.Marker} marker The marker to add.
* @param {boolean=} opt_nodraw Whether to redraw the clusters.
*/
MarkerClusterer.prototype.addMarker = function(marker, opt_nodraw) {
this.pushMarkerTo_(marker);
if (!opt_nodraw) {
this.redraw();
}
};
/**
* Removes a marker and returns true if removed, false if not
*
* @param {google.maps.Marker} marker The marker to remove
* @return {boolean} Whether the marker was removed or not
* @private
*/
MarkerClusterer.prototype.removeMarker_ = function(marker) {
var index = -1;
if (this.markers_.indexOf) {
index = this.markers_.indexOf(marker);
} else {
for (var i = 0, m; m = this.markers_[i]; i++) {
if (m == marker) {
index = i;
break;
}
}
}
if (index == -1) {
// Marker is not in our list of markers.
return false;
}
marker.setMap(null);
this.markers_.splice(index, 1);
return true;
};
/**
* Remove a marker from the cluster.
*
* @param {google.maps.Marker} marker The marker to remove.
* @param {boolean=} opt_nodraw Optional boolean to force no redraw.
* @return {boolean} True if the marker was removed.
*/
MarkerClusterer.prototype.removeMarker = function(marker, opt_nodraw) {
var removed = this.removeMarker_(marker);
if (!opt_nodraw && removed) {
this.resetViewport();
this.redraw();
return true;
} else {
return false;
}
};
/**
* Removes an array of markers from the cluster.
*
* @param {Array.} markers The markers to remove.
* @param {boolean=} opt_nodraw Optional boolean to force no redraw.
*/
MarkerClusterer.prototype.removeMarkers = function(markers, opt_nodraw) {
var removed = false;
for (var i = 0, marker; marker = markers[i]; i++) {
var r = this.removeMarker_(marker);
removed = removed || r;
}
if (!opt_nodraw && removed) {
this.resetViewport();
this.redraw();
return true;
}
};
/**
* Sets the clusterer's ready state.
*
* @param {boolean} ready The state.
* @private
*/
MarkerClusterer.prototype.setReady_ = function(ready) {
if (!this.ready_) {
this.ready_ = ready;
this.createClusters_();
}
};
/**
* Returns the number of clusters in the clusterer.
*
* @return {number} The number of clusters.
*/
MarkerClusterer.prototype.getTotalClusters = function() {
return this.clusters_.length;
};
/**
* Returns the google map that the clusterer is associated with.
*
* @return {google.maps.Map} The map.
*/
MarkerClusterer.prototype.getMap = function() {
return this.map_;
};
/**
* Sets the google map that the clusterer is associated with.
*
* @param {google.maps.Map} map The map.
*/
MarkerClusterer.prototype.setMap = function(map) {
this.map_ = map;
};
/**
* Returns the size of the grid.
*
* @return {number} The grid size.
*/
MarkerClusterer.prototype.getGridSize = function() {
return this.gridSize_;
};
/**
* Sets the size of the grid.
*
* @param {number} size The grid size.
*/
MarkerClusterer.prototype.setGridSize = function(size) {
this.gridSize_ = size;
};
/**
* Returns the min cluster size.
*
* @return {number} The grid size.
*/
MarkerClusterer.prototype.getMinClusterSize = function() {
return this.minClusterSize_;
};
/**
* Sets the min cluster size.
*
* @param {number} size The grid size.
*/
MarkerClusterer.prototype.setMinClusterSize = function(size) {
this.minClusterSize_ = size;
};
/**
* Extends a bounds object by the grid size.
*
* @param {google.maps.LatLngBounds} bounds The bounds to extend.
* @return {google.maps.LatLngBounds} The extended bounds.
*/
MarkerClusterer.prototype.getExtendedBounds = function(bounds) {
var projection = this.getProjection();
// Turn the bounds into latlng.
var tr = new google.maps.LatLng(bounds.getNorthEast().lat(),
bounds.getNorthEast().lng());
var bl = new google.maps.LatLng(bounds.getSouthWest().lat(),
bounds.getSouthWest().lng());
// Convert the points to pixels and the extend out by the grid size.
var trPix = projection.fromLatLngToDivPixel(tr);
trPix.x += this.gridSize_;
trPix.y -= this.gridSize_;
var blPix = projection.fromLatLngToDivPixel(bl);
blPix.x -= this.gridSize_;
blPix.y += this.gridSize_;
// Convert the pixel points back to LatLng
var ne = projection.fromDivPixelToLatLng(trPix);
var sw = projection.fromDivPixelToLatLng(blPix);
// Extend the bounds to contain the new bounds.
bounds.extend(ne);
bounds.extend(sw);
return bounds;
};
/**
* Determins if a marker is contained in a bounds.
*
* @param {google.maps.Marker} marker The marker to check.
* @param {google.maps.LatLngBounds} bounds The bounds to check against.
* @return {boolean} True if the marker is in the bounds.
* @private
*/
MarkerClusterer.prototype.isMarkerInBounds_ = function(marker, bounds) {
return bounds.contains(marker.getPosition());
};
/**
* Clears all clusters and markers from the clusterer.
*/
MarkerClusterer.prototype.clearMarkers = function() {
this.resetViewport(true);
// Set the markers a empty array.
this.markers_ = [];
};
/**
* Clears all existing clusters and recreates them.
* @param {boolean} opt_hide To also hide the marker.
*/
MarkerClusterer.prototype.resetViewport = function(opt_hide) {
// Remove all the clusters
for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
cluster.remove();
}
// Reset the markers to not be added and to be invisible.
for (var i = 0, marker; marker = this.markers_[i]; i++) {
marker.isAdded = false;
if (opt_hide) {
marker.setMap(null);
}
}
this.clusters_ = [];
};
/**
*
*/
MarkerClusterer.prototype.repaint = function() {
var oldClusters = this.clusters_.slice();
this.clusters_.length = 0;
this.resetViewport();
this.redraw();
// Remove the old clusters.
// Do it in a timeout so the other clusters have been drawn first.
window.setTimeout(function() {
for (var i = 0, cluster; cluster = oldClusters[i]; i++) {
cluster.remove();
}
}, 0);
};
/**
* Redraws the clusters.
*/
MarkerClusterer.prototype.redraw = function() {
this.createClusters_();
};
/**
* Calculates the distance between two latlng locations in km.
* @see http://www.movable-type.co.uk/scripts/latlong.html
*
* @param {google.maps.LatLng} p1 The first lat lng point.
* @param {google.maps.LatLng} p2 The second lat lng point.
* @return {number} The distance between the two points in km.
* @private
*/
MarkerClusterer.prototype.distanceBetweenPoints_ = function(p1, p2) {
if (!p1 || !p2) {
return 0;
}
var R = 6371; // Radius of the Earth in km
var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
/**
* Add a marker to a cluster, or creates a new cluster.
*
* @param {google.maps.Marker} marker The marker to add.
* @private
*/
MarkerClusterer.prototype.addToClosestCluster_ = function(marker) {
var distance = 40000; // Some large number
var clusterToAddTo = null;
var pos = marker.getPosition();
for (var i = 0, cluster; cluster = this.clusters_[i]; i++) {
var center = cluster.getCenter();
if (center) {
var d = this.distanceBetweenPoints_(center, marker.getPosition());
if (d < distance) {
distance = d;
clusterToAddTo = cluster;
}
}
}
if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) {
clusterToAddTo.addMarker(marker);
} else {
var cluster = new Cluster(this);
cluster.addMarker(marker);
this.clusters_.push(cluster);
}
};
/**
* Creates the clusters.
*
* @private
*/
MarkerClusterer.prototype.createClusters_ = function() {
if (!this.ready_) {
return;
}
// Get our current map view bounds.
// Create a new bounds object so we don't affect the map.
var mapBounds = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(),
this.map_.getBounds().getNorthEast());
var bounds = this.getExtendedBounds(mapBounds);
for (var i = 0, marker; marker = this.markers_[i]; i++) {
if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) {
this.addToClosestCluster_(marker);
}
}
};
/**
* A cluster that contains markers.
*
* @param {MarkerClusterer} markerClusterer The markerclusterer that this
* cluster is associated with.
* @constructor
* @ignore
*/
function Cluster(markerClusterer) {
this.markerClusterer_ = markerClusterer;
this.map_ = markerClusterer.getMap();
this.gridSize_ = markerClusterer.getGridSize();
this.minClusterSize_ = markerClusterer.getMinClusterSize();
this.averageCenter_ = markerClusterer.isAverageCenter();
this.center_ = null;
this.markers_ = [];
this.bounds_ = null;
this.clusterIcon_ = new ClusterIcon(this, markerClusterer.getStyles(),
markerClusterer.getGridSize());
}
/**
* Determins if a marker is already added to the cluster.
*
* @param {google.maps.Marker} marker The marker to check.
* @return {boolean} True if the marker is already added.
*/
Cluster.prototype.isMarkerAlreadyAdded = function(marker) {
if (this.markers_.indexOf) {
return this.markers_.indexOf(marker) != -1;
} else {
for (var i = 0, m; m = this.markers_[i]; i++) {
if (m == marker) {
return true;
}
}
}
return false;
};
/**
* Add a marker the cluster.
*
* @param {google.maps.Marker} marker The marker to add.
* @return {boolean} True if the marker was added.
*/
Cluster.prototype.addMarker = function(marker) {
if (this.isMarkerAlreadyAdded(marker)) {
return false;
}
if (!this.center_) {
this.center_ = marker.getPosition();
this.calculateBounds_();
} else {
if (this.averageCenter_) {
var l = this.markers_.length + 1;
var lat = (this.center_.lat() * (l-1) + marker.getPosition().lat()) / l;
var lng = (this.center_.lng() * (l-1) + marker.getPosition().lng()) / l;
this.center_ = new google.maps.LatLng(lat, lng);
this.calculateBounds_();
}
}
marker.isAdded = true;
this.markers_.push(marker);
var len = this.markers_.length;
if (len < this.minClusterSize_ && marker.getMap() != this.map_) {
// Min cluster size not reached so show the marker.
marker.setMap(this.map_);
}
if (len == this.minClusterSize_) {
// Hide the markers that were showing.
for (var i = 0; i < len; i++) {
this.markers_[i].setMap(null);
}
}
if (len >= this.minClusterSize_) {
marker.setMap(null);
}
this.updateIcon();
return true;
};
/**
* Returns the marker clusterer that the cluster is associated with.
*
* @return {MarkerClusterer} The associated marker clusterer.
*/
Cluster.prototype.getMarkerClusterer = function() {
return this.markerClusterer_;
};
/**
* Returns the bounds of the cluster.
*
* @return {google.maps.LatLngBounds} the cluster bounds.
*/
Cluster.prototype.getBounds = function() {
var bounds = new google.maps.LatLngBounds(this.center_, this.center_);
var markers = this.getMarkers();
for (var i = 0, marker; marker = markers[i]; i++) {
bounds.extend(marker.getPosition());
}
return bounds;
};
/**
* Removes the cluster
*/
Cluster.prototype.remove = function() {
this.clusterIcon_.remove();
this.markers_.length = 0;
delete this.markers_;
};
/**
* Returns the center of the cluster.
*
* @return {number} The cluster center.
*/
Cluster.prototype.getSize = function() {
return this.markers_.length;
};
/**
* Returns the center of the cluster.
*
* @return {Array.} The cluster center.
*/
Cluster.prototype.getMarkers = function() {
return this.markers_;
};
/**
* Returns the center of the cluster.
*
* @return {google.maps.LatLng} The cluster center.
*/
Cluster.prototype.getCenter = function() {
return this.center_;
};
/**
* Calculated the extended bounds of the cluster with the grid.
*
* @private
*/
Cluster.prototype.calculateBounds_ = function() {
var bounds = new google.maps.LatLngBounds(this.center_, this.center_);
this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds);
};
/**
* Determines if a marker lies in the clusters bounds.
*
* @param {google.maps.Marker} marker The marker to check.
* @return {boolean} True if the marker lies in the bounds.
*/
Cluster.prototype.isMarkerInClusterBounds = function(marker) {
return this.bounds_.contains(marker.getPosition());
};
/**
* Returns the map that the cluster is associated with.
*
* @return {google.maps.Map} The map.
*/
Cluster.prototype.getMap = function() {
return this.map_;
};
/**
* Updates the cluster icon
*/
Cluster.prototype.updateIcon = function() {
var zoom = this.map_.getZoom();
var mz = this.markerClusterer_.getMaxZoom();
if (mz && zoom > mz) {
// The zoom is greater than our max zoom so show all the markers in cluster.
for (var i = 0, marker; marker = this.markers_[i]; i++) {
marker.setMap(this.map_);
}
return;
}
if (this.markers_.length < this.minClusterSize_) {
// Min cluster size not yet reached.
this.clusterIcon_.hide();
return;
}
var numStyles = this.markerClusterer_.getStyles().length;
var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles);
this.clusterIcon_.setCenter(this.center_);
this.clusterIcon_.setSums(sums);
this.clusterIcon_.show();
};
/**
* A cluster icon
*
* @param {Cluster} cluster The cluster to be associated with.
* @param {Object} styles An object that has style properties:
* 'url': (string) The image url.
* 'height': (number) The image height.
* 'width': (number) The image width.
* 'anchor': (Array) The anchor position of the label text.
* 'textColor': (string) The text color.
* 'textSize': (number) The text size.
* 'backgroundPosition: (string) The background postition x, y.
* @param {number=} opt_padding Optional padding to apply to the cluster icon.
* @constructor
* @extends google.maps.OverlayView
* @ignore
*/
function ClusterIcon(cluster, styles, opt_padding) {
cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView);
this.styles_ = styles;
this.padding_ = opt_padding || 0;
this.cluster_ = cluster;
this.center_ = null;
this.map_ = cluster.getMap();
this.div_ = null;
this.sums_ = null;
this.visible_ = false;
this.setMap(this.map_);
}
/**
* Triggers the clusterclick event and zoom's if the option is set.
*/
ClusterIcon.prototype.triggerClusterClick = function() {
var markerClusterer = this.cluster_.getMarkerClusterer();
// Trigger the clusterclick event.
google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
if(g.data.clustering_click == "list"){
// show infowindow with marker content
cluster_infowindow=new google.maps.InfoWindow();
var markers = this.cluster_.getMarkers();
var html = '';
var marker_link = '';
var marker_icon = '';
var marker_title = '';
var marker_desc = '';
html += ''+ markers.length + ' markers';
html += '