// 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";
var limit_object = -1;
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;";
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 += '
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[8.884585256682271,40.09416518750004],\"visible\":true,\"title\":\"Church Support and Economic Development\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Church Support and Economic Development
About the Ministry: Anthem Friends is helping to support a church in Kora, a small city built on the capital city’s dump, as well as providing income-generating activities for those living in this area.
About the Ministry: Mark Wolbert of Anthem Friends is serving as the Missions Director of YWAM’s adoption ministry in Ethiopia.
Contact Info:
Kameron Shadrick: (208)-262-6186
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[9.438663175435432,42.68693862500004],\"visible\":true,\"title\":\"Glimmer of Hope\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Glimmer of Hope
About the Ministry: East Hills Friends partners with this organization providing water, medical, and educational projects in this region.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[15.68829976252027,-90.34062228124998],\"visible\":true,\"title\":\"El Amor de Patricia Orphanage\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: El Amor do Patricia Orphanage
About the Ministry:
Anthem Friends sponsors and regularly visits this orphanage.
Contact Info:
Kameron Shadrick: (208)-262-6186
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[18.973409244075075,-72.52700231796877],\"visible\":true,\"title\":\"Short Term Medical Teams\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Short Term Medical Teams
About the Ministry: West Hills Friends sent a team of four medical workers on a short-term mission in spring of 2011. They anticipate sending another in 2012.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[0.4392357692792226,38.02429602734378],\"visible\":true,\"title\":\"Friendly Water for the World\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Friendly Water for the World
About the Ministry: Del and Susanne Livingston of Olympic View Friends go around the world to provide clean water projects for underdeveloped regions and train others to do likewise. Our projects are currently happening in Kenya, Uganda, Burundi, Democratic Republic of Congo, and Honduras.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[0.665643153557302,36.88171790234378],\"visible\":true,\"title\":\"Short Term Medical Teams\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Short Term Medical Teams
About the Ministry: Jan and Conrad Schmeltzer of Reedwood Friends make regular short-term trips to Friends Lugulu Mission Hospital in western Kenya.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[26.32300053627014,-104.29274371679679],\"visible\":true,\"title\":\"YWAM Short Term Missions\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: YWAM Short Term Missions
About the Ministry: Medford Friends Church makes a trip to Mexico each year to build a house through a ministry of YWAM.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[25.20498187261539,-102.38112262304685],\"visible\":true,\"title\":\"Short Term Missions Teams\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry:
Short Term Missions
About the Ministry: Rose Valley Friends sends a team to Mexico each year for Spring Break.
About the Ministry: Lorie Wood of West Hills Friends partners with olive growers in Palestine to provide a fair trade market for their products in the northwest.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[7.577604925292531,29.899291695312513],\"visible\":true,\"title\":\"Clean Water for the World\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Clean Water for the World
About the Ministry: Bob Bonaci of Olympic View Friends has traveled to South Sudan with a group from Puget Sound to provide water filtration systems.
About the Ministry: Jeff and Christine Stanfield of 2nd Street Community Church are serving as long-term missionaries working to equip local people to answer God’s call.
\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[45.64221776584902,-122.65613108758544],\"visible\":true,\"title\":\"Vancouver Peace and Justice Fair\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Vancouver Peace and Justice Fair
About the Ministry: West Hills Friends partners with Vancouver area churches and organizations in September for a weekend event promoting peace and justice.
Contact Info:
Kay Ellison: (360)-696-4840
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[45.47106473339548,-122.73084883254091],\"visible\":true,\"title\":\"Friends Committee on National Legislation\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Friends Committee on National Legislation
About the Ministry: Mike Huber of West Hills Friends works with FCNL to lobby for peace and justice in American policies.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[43.60149314475838,-116.2111980156235],\"visible\":true,\"title\":\"Christian Medical and Dental Association\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Christian Medical and Dental Association
About the Ministry: Janice Pina of Boise Friends works with CMDA to do short-term medical missions to areas of need.
About the Ministry: Jerry Kingrey of 2nd Street Friends works to distribute bibles around the world. Â Chapters Books and Coffee serves as a drop-off location for Bibles..
About the Ministry: Hal and Nancy Thomas work with the Latin America Doctoral Program in Theology (PRODOLA), an academic program geared to meet the leadership needs of the growing church in Latin America.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[-3.3432189544846227,29.934997261718763],\"visible\":true,\"title\":\"Peace through Pieces\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Peace through Pieces
About the Ministry:
Patty Federighi and Carolann Palmer of North Seattle Friends provide quilt-making training to trauma victims in order to bring reconciliation and hope to war-torn communities. Â They partner with Trauma Healing and Reconciliation Services, a ministry of Friends in Burundi.
\",\"maxWidth\":\"0\"}}}},\"catID\":\"-1\"},{\"iconid\":\"33\",\"options\":{\"position\":[-13.54966833879357,33.82965058203126],\"visible\":true,\"title\":\"Short Term Missions\"},\"event\":{\"click\":{\"infoWindow\":{\"options\":{\"content\":\"
Ministry: Short Term Missions
About the Ministry:
Cherry Grove Friends has sent three teams to Lilongwe, Malawi in order to build homes for local orphans and street kids in the care of Samuel Kayuni. They have also visited churches and hospitals in the area.
About the Ministry: North Seattle Friends Church supports a medical mission project of Honduras Yearly Meeting. Since 2002, Portia Jones and her husband Jonathan Hibbs have made over 25 trips to northwestern Honduras to train health promoters, selected by Friends churches, who treat, on average, 3 people per week in remote mountain villages. The entire project is under the direction of the Intergrated Development Team, a committee of Honduras Yealy Meeting.
About the Ministry: QVS is a year-long experience for Friends to serve local communities around the United States within the context of a small, local community. A member of West Hills Friends is currently serving for one year at the Quaker Voluntary Services (QVS) location in Atlanta, GA.