forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			1758 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			1758 lines
		
	
	
		
			44 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								(function(){
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @exports mxn.util.$m as $m
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var $m = mxn.util.$m;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Initialise our provider. This function should only be called 
							 | 
						||
| 
								 | 
							
								 * from within mapstraction code, not exposed as part of the API.
							 | 
						||
| 
								 | 
							
								 * @private
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var init = function() {
							 | 
						||
| 
								 | 
							
									this.invoker.go('init', [ this.currentElement, this.api ]);
							 | 
						||
| 
								 | 
							
									this.applyOptions();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Mapstraction instantiates a map with some API choice into the HTML element given
							 | 
						||
| 
								 | 
							
								 * @name mxn.Mapstraction
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {String} element The HTML element to replace with a map
							 | 
						||
| 
								 | 
							
								 * @param {String} api The API to use, one of 'google', 'googlev3', 'yahoo', 'microsoft', 'openstreetmap', 'multimap', 'map24', 'openlayers', 'mapquest'. If omitted, first loaded provider implementation is used.
							 | 
						||
| 
								 | 
							
								 * @param {Bool} debug optional parameter to turn on debug support - this uses alert panels for unsupported actions
							 | 
						||
| 
								 | 
							
								 * @exports Mapstraction as mxn.Mapstraction
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var Mapstraction = mxn.Mapstraction = function(element, api, debug) {
							 | 
						||
| 
								 | 
							
								    if (!api){
							 | 
						||
| 
								 | 
							
										api = mxn.util.getAvailableProviders()[0];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									this.api = api;
							 | 
						||
| 
								 | 
							
									this.maps = {};
							 | 
						||
| 
								 | 
							
									this.currentElement = $m(element);
							 | 
						||
| 
								 | 
							
									this.eventListeners = [];
							 | 
						||
| 
								 | 
							
									this.markers = [];
							 | 
						||
| 
								 | 
							
									this.layers = [];
							 | 
						||
| 
								 | 
							
									this.polylines = [];
							 | 
						||
| 
								 | 
							
									this.images = [];
							 | 
						||
| 
								 | 
							
								        this.controls = [];	
							 | 
						||
| 
								 | 
							
									this.loaded = {};
							 | 
						||
| 
								 | 
							
									this.onload = {};
							 | 
						||
| 
								 | 
							
									this.element = element;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									// option defaults
							 | 
						||
| 
								 | 
							
									this.options = {
							 | 
						||
| 
								 | 
							
										enableScrollWheelZoom: false,
							 | 
						||
| 
								 | 
							
										enableDragging: true
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									this.addControlsArgs = {};
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									// set up our invoker for calling API methods
							 | 
						||
| 
								 | 
							
									this.invoker = new mxn.Invoker(this, 'Mapstraction', function(){ return this.api; });
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									// Adding our events
							 | 
						||
| 
								 | 
							
									mxn.addEvents(this, [
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Map has loaded
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#load
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'load',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Map is clicked {location: LatLonPoint}
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#click
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'click',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Map is panned
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#endPan
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'endPan',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Zoom is changed
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#changeZoom
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'changeZoom',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Marker is removed {marker: Marker}
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#markerAdded
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'markerAdded',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Marker is removed {marker: Marker}
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#markerRemoved
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'markerRemoved',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Polyline is added {polyline: Polyline}
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#polylineAdded
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'polylineAdded',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										/**
							 | 
						||
| 
								 | 
							
										 * Polyline is removed {polyline: Polyline}
							 | 
						||
| 
								 | 
							
										 * @name mxn.Mapstraction#polylineRemoved
							 | 
						||
| 
								 | 
							
										 * @event
							 | 
						||
| 
								 | 
							
										 */
							 | 
						||
| 
								 | 
							
										'polylineRemoved'
							 | 
						||
| 
								 | 
							
									]);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									// finally initialize our proper API map
							 | 
						||
| 
								 | 
							
									init.apply(this);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Map type constants
							 | 
						||
| 
								 | 
							
								Mapstraction.ROAD = 1;
							 | 
						||
| 
								 | 
							
								Mapstraction.SATELLITE = 2;
							 | 
						||
| 
								 | 
							
								Mapstraction.HYBRID = 3;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// methods that have no implementation in mapstraction core
							 | 
						||
| 
								 | 
							
								mxn.addProxyMethods(Mapstraction, [ 
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Adds a large map panning control and zoom buttons to the map
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#addLargeControls
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'addLargeControls',
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Adds a map type control to the map (streets, aerial imagery etc)
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#addMapTypeControls
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'addMapTypeControls', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Adds a GeoRSS or KML overlay to the map
							 | 
						||
| 
								 | 
							
									 *  some flavors of GeoRSS and KML are not supported by some of the Map providers
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#addOverlay
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {String} url GeoRSS or KML feed URL
							 | 
						||
| 
								 | 
							
									 * @param {Boolean} autoCenterAndZoom Set true to auto center and zoom after the feed is loaded
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'addOverlay', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Adds a small map panning control and zoom buttons to the map
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#addSmallControls
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'addSmallControls', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Applies the current option settings
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#applyOptions
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'applyOptions',
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Gets the BoundingBox of the map
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#getBounds
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @returns {BoundingBox} The bounding box for the current map state
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'getBounds', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Gets the central point of the map
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#getCenter
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @returns {LatLonPoint} The center point of the map
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'getCenter', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Gets the imagery type for the map.
							 | 
						||
| 
								 | 
							
									 * The type can be one of:
							 | 
						||
| 
								 | 
							
									 *  mxn.Mapstraction.ROAD
							 | 
						||
| 
								 | 
							
									 *  mxn.Mapstraction.SATELLITE
							 | 
						||
| 
								 | 
							
									 *  mxn.Mapstraction.HYBRID
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#getMapType
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @returns {Number} 
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'getMapType', 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Returns a ratio to turn distance into pixels based on current projection
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#getPixelRatio
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @returns {Float} ratio
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'getPixelRatio', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Returns the zoom level of the map
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#getZoom
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @returns {Integer} The zoom level of the map
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'getZoom', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Returns the best zoom level for bounds given
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#getZoomLevelForBoundingBox
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {BoundingBox} bbox The bounds to fit
							 | 
						||
| 
								 | 
							
									 * @returns {Integer} The closest zoom level that contains the bounding box
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'getZoomLevelForBoundingBox', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Displays the coordinates of the cursor in the HTML element
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#mousePosition
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {String} element ID of the HTML element to display the coordinates in
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'mousePosition',
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Resize the current map to the specified width and height
							 | 
						||
| 
								 | 
							
									 * (since it is actually on a child div of the mapElement passed
							 | 
						||
| 
								 | 
							
									 * as argument to the Mapstraction constructor, the resizing of this
							 | 
						||
| 
								 | 
							
									 * mapElement may have no effect on the size of the actual map)
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#resizeTo
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {Integer} width The width the map should be.
							 | 
						||
| 
								 | 
							
									 * @param {Integer} height The width the map should be.
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'resizeTo', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Sets the map to the appropriate location and zoom for a given BoundingBox
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#setBounds
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {BoundingBox} bounds The bounding box you want the map to show
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'setBounds', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * setCenter sets the central point of the map
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#setCenter
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {LatLonPoint} point The point at which to center the map
							 | 
						||
| 
								 | 
							
									 * @param {Object} options Optional parameters
							 | 
						||
| 
								 | 
							
									 * @param {Boolean} options.pan Whether the map should move to the locations using a pan or just jump straight there
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'setCenter', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Centers the map to some place and zoom level
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#setCenterAndZoom
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {LatLonPoint} point Where the center of the map should be
							 | 
						||
| 
								 | 
							
									 * @param {Integer} zoom The zoom level where 0 is all the way out.
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'setCenterAndZoom', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Sets the imagery type for the map
							 | 
						||
| 
								 | 
							
									 * The type can be one of:
							 | 
						||
| 
								 | 
							
									 *  mxn.Mapstraction.ROAD
							 | 
						||
| 
								 | 
							
									 *  mxn.Mapstraction.SATELLITE
							 | 
						||
| 
								 | 
							
									 *  mxn.Mapstraction.HYBRID
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#setMapType
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {Number} type 
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'setMapType', 
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Sets the zoom level for the map
							 | 
						||
| 
								 | 
							
									 * MS doesn't seem to do zoom=0, and Gg's sat goes closer than it's maps, and MS's sat goes closer than Y!'s
							 | 
						||
| 
								 | 
							
									 * TODO: Mapstraction.prototype.getZoomLevels or something.
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#setZoom
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {Number} zoom The (native to the map) level zoom the map to.
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'setZoom',
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/**
							 | 
						||
| 
								 | 
							
									 * Turns a Tile Layer on or off
							 | 
						||
| 
								 | 
							
									 * @name mxn.Mapstraction#toggleTileLayer
							 | 
						||
| 
								 | 
							
									 * @function
							 | 
						||
| 
								 | 
							
									 * @param {tile_url} url of the tile layer that was created.
							 | 
						||
| 
								 | 
							
									 */
							 | 
						||
| 
								 | 
							
									'toggleTileLayer'
							 | 
						||
| 
								 | 
							
								]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Sets the current options to those specified in oOpts and applies them
							 | 
						||
| 
								 | 
							
								 * @param {Object} oOpts Hash of options to set
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.setOptions = function(oOpts){
							 | 
						||
| 
								 | 
							
									mxn.util.merge(this.options, oOpts);
							 | 
						||
| 
								 | 
							
									this.applyOptions();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Sets an option and applies it.
							 | 
						||
| 
								 | 
							
								 * @param {String} sOptName Option name
							 | 
						||
| 
								 | 
							
								 * @param vVal Option value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.setOption = function(sOptName, vVal){
							 | 
						||
| 
								 | 
							
									this.options[sOptName] = vVal;
							 | 
						||
| 
								 | 
							
									this.applyOptions();
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Enable scroll wheel zooming
							 | 
						||
| 
								 | 
							
								 * @deprecated Use setOption instead.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.enableScrollWheelZoom = function() {
							 | 
						||
| 
								 | 
							
									this.setOption('enableScrollWheelZoom', true);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Enable/disable dragging of the map
							 | 
						||
| 
								 | 
							
								 * @param {Boolean} on
							 | 
						||
| 
								 | 
							
								 * @deprecated Use setOption instead.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.dragging = function(on) {
							 | 
						||
| 
								 | 
							
									this.setOption('enableDragging', on);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Change the current api on the fly
							 | 
						||
| 
								 | 
							
								 * @param {String} api The API to swap to
							 | 
						||
| 
								 | 
							
								 * @param element
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.swap = function(element,api) {
							 | 
						||
| 
								 | 
							
									if (this.api === api) {
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var center = this.getCenter();
							 | 
						||
| 
								 | 
							
									var zoom = this.getZoom();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.currentElement.style.visibility = 'hidden';
							 | 
						||
| 
								 | 
							
									this.currentElement.style.display = 'none';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.currentElement = $m(element);
							 | 
						||
| 
								 | 
							
									this.currentElement.style.visibility = 'visible';
							 | 
						||
| 
								 | 
							
									this.currentElement.style.display = 'block';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.api = api;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (this.maps[this.api] === undefined) {
							 | 
						||
| 
								 | 
							
										init.apply(this);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.setCenterAndZoom(center,zoom);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (var i = 0; i < this.markers.length; i++) {
							 | 
						||
| 
								 | 
							
											this.addMarker(this.markers[i], true);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for (var j = 0; j < this.polylines.length; j++) {
							 | 
						||
| 
								 | 
							
											this.addPolyline( this.polylines[j], true);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//sync the view
							 | 
						||
| 
								 | 
							
										this.setCenterAndZoom(center,zoom);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										//TODO synchronize the markers and polylines too
							 | 
						||
| 
								 | 
							
										// (any overlays created after api instantiation are not sync'd)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.addControls(this.addControlsArgs);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Returns the loaded state of a Map Provider
							 | 
						||
| 
								 | 
							
								 * @param {String} api Optional API to query for. If not specified, returns state of the originally created API
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.isLoaded = function(api){
							 | 
						||
| 
								 | 
							
									if (api === null) {
							 | 
						||
| 
								 | 
							
										api = this.api;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return this.loaded[api];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Set the debugging on or off - shows alert panels for functions that don't exist in Mapstraction
							 | 
						||
| 
								 | 
							
								 * @param {Boolean} debug true to turn on debugging, false to turn it off
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.setDebug = function(debug){
							 | 
						||
| 
								 | 
							
									if(debug !== null) {
							 | 
						||
| 
								 | 
							
										this.debug = debug;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return this.debug;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Event Handling
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// FIXME need to consolidate some of these handlers...
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								///////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Click handler attached to native API
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.clickHandler = function(lat, lon, me) {
							 | 
						||
| 
								 | 
							
									this.callEventListeners('click', {
							 | 
						||
| 
								 | 
							
										location: new LatLonPoint(lat, lon)
							 | 
						||
| 
								 | 
							
									});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Move and zoom handler attached to native API
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.moveendHandler = function(me) {
							 | 
						||
| 
								 | 
							
									this.callEventListeners('moveend', {});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Add a listener for an event.
							 | 
						||
| 
								 | 
							
								 * @param {String} type Event type to attach listener to
							 | 
						||
| 
								 | 
							
								 * @param {Function} func Callback function
							 | 
						||
| 
								 | 
							
								 * @param {Object} caller Callback object
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addEventListener = function() {
							 | 
						||
| 
								 | 
							
									var listener = {};
							 | 
						||
| 
								 | 
							
									listener.event_type = arguments[0];
							 | 
						||
| 
								 | 
							
									listener.callback_function = arguments[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// added the calling object so we can retain scope of callback function
							 | 
						||
| 
								 | 
							
									if(arguments.length == 3) {
							 | 
						||
| 
								 | 
							
										listener.back_compat_mode = false;
							 | 
						||
| 
								 | 
							
										listener.callback_object = arguments[2];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										listener.back_compat_mode = true;
							 | 
						||
| 
								 | 
							
										listener.callback_object = null;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									this.eventListeners.push(listener);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Call listeners for a particular event.
							 | 
						||
| 
								 | 
							
								 * @param {String} sEventType Call listeners of this event type
							 | 
						||
| 
								 | 
							
								 * @param {Object} oEventArgs Event args object to pass back to the callback
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.callEventListeners = function(sEventType, oEventArgs) {
							 | 
						||
| 
								 | 
							
									oEventArgs.source = this;
							 | 
						||
| 
								 | 
							
									for(var i = 0; i < this.eventListeners.length; i++) {
							 | 
						||
| 
								 | 
							
										var evLi = this.eventListeners[i];
							 | 
						||
| 
								 | 
							
										if(evLi.event_type == sEventType) {
							 | 
						||
| 
								 | 
							
											// only two cases for this, click and move
							 | 
						||
| 
								 | 
							
											if(evLi.back_compat_mode) {
							 | 
						||
| 
								 | 
							
												if(evLi.event_type == 'click') {
							 | 
						||
| 
								 | 
							
													evLi.callback_function(oEventArgs.location);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												else {
							 | 
						||
| 
								 | 
							
													evLi.callback_function();
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											else {
							 | 
						||
| 
								 | 
							
												var scope = evLi.callback_object || this;
							 | 
						||
| 
								 | 
							
												evLi.callback_function.call(scope, oEventArgs);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// map manipulation
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								/////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addControls adds controls to the map. You specify which controls to add in
							 | 
						||
| 
								 | 
							
								 * the associative array that is the only argument.
							 | 
						||
| 
								 | 
							
								 * addControls can be called multiple time, with different args, to dynamically change controls.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * args = {
							 | 
						||
| 
								 | 
							
								 *	 pan:	  true,
							 | 
						||
| 
								 | 
							
								 *	 zoom:	 'large' || 'small',
							 | 
						||
| 
								 | 
							
								 *	 overview: true,
							 | 
						||
| 
								 | 
							
								 *	 scale:	true,
							 | 
						||
| 
								 | 
							
								 *	 map_type: true,
							 | 
						||
| 
								 | 
							
								 * }
							 | 
						||
| 
								 | 
							
								 * @param {array} args Which controls to switch on
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addControls = function( args ) {
							 | 
						||
| 
								 | 
							
									this.addControlsArgs = args;
							 | 
						||
| 
								 | 
							
									this.invoker.go('addControls', arguments);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Adds a marker pin to the map
							 | 
						||
| 
								 | 
							
								 * @param {Marker} marker The marker to add
							 | 
						||
| 
								 | 
							
								 * @param {Boolean} old If true, doesn't add this marker to the markers array. Used by the "swap" method
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addMarker = function(marker, old) {
							 | 
						||
| 
								 | 
							
									marker.mapstraction = this;
							 | 
						||
| 
								 | 
							
									marker.api = this.api;
							 | 
						||
| 
								 | 
							
									marker.location.api = this.api;
							 | 
						||
| 
								 | 
							
									marker.map = this.maps[this.api]; 
							 | 
						||
| 
								 | 
							
									var propMarker = this.invoker.go('addMarker', arguments);
							 | 
						||
| 
								 | 
							
									marker.setChild(propMarker);
							 | 
						||
| 
								 | 
							
									if (!old) {
							 | 
						||
| 
								 | 
							
										this.markers.push(marker);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									this.markerAdded.fire({'marker': marker});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addMarkerWithData will addData to the marker, then add it to the map
							 | 
						||
| 
								 | 
							
								 * @param {Marker} marker The marker to add
							 | 
						||
| 
								 | 
							
								 * @param {Object} data A data has to add
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addMarkerWithData = function(marker, data) {
							 | 
						||
| 
								 | 
							
									marker.addData(data);
							 | 
						||
| 
								 | 
							
									this.addMarker(marker);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addPolylineWithData will addData to the polyline, then add it to the map
							 | 
						||
| 
								 | 
							
								 * @param {Polyline} polyline The polyline to add
							 | 
						||
| 
								 | 
							
								 * @param {Object} data A data has to add
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addPolylineWithData = function(polyline, data) {
							 | 
						||
| 
								 | 
							
									polyline.addData(data);
							 | 
						||
| 
								 | 
							
									this.addPolyline(polyline);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * removeMarker removes a Marker from the map
							 | 
						||
| 
								 | 
							
								 * @param {Marker} marker The marker to remove
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.removeMarker = function(marker) {	
							 | 
						||
| 
								 | 
							
									var current_marker;
							 | 
						||
| 
								 | 
							
									for(var i = 0; i < this.markers.length; i++){
							 | 
						||
| 
								 | 
							
										current_marker = this.markers[i];
							 | 
						||
| 
								 | 
							
										if(marker == current_marker) {
							 | 
						||
| 
								 | 
							
											this.invoker.go('removeMarker', arguments);
							 | 
						||
| 
								 | 
							
											marker.onmap = false;
							 | 
						||
| 
								 | 
							
											this.markers.splice(i, 1);
							 | 
						||
| 
								 | 
							
											this.markerRemoved.fire({'marker': marker});
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * removeAllMarkers removes all the Markers on a map
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.removeAllMarkers = function() {
							 | 
						||
| 
								 | 
							
									var current_marker;
							 | 
						||
| 
								 | 
							
									while(this.markers.length > 0) {
							 | 
						||
| 
								 | 
							
										current_marker = this.markers.pop();
							 | 
						||
| 
								 | 
							
										this.invoker.go('removeMarker', [current_marker]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Declutter the markers on the map, group together overlapping markers.
							 | 
						||
| 
								 | 
							
								 * @param {Object} opts Declutter options
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.declutterMarkers = function(opts) {
							 | 
						||
| 
								 | 
							
									if(this.loaded[this.api] === false) {
							 | 
						||
| 
								 | 
							
										var me = this;
							 | 
						||
| 
								 | 
							
										this.onload[this.api].push( function() {
							 | 
						||
| 
								 | 
							
											me.declutterMarkers(opts);
							 | 
						||
| 
								 | 
							
										} );
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var map = this.maps[this.api];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									switch(this.api)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										//	case 'yahoo':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										//	case 'google':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										//	case 'openstreetmap':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										//	case 'microsoft':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										//	case 'openlayers':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										case 'multimap':
							 | 
						||
| 
								 | 
							
											/*
							 | 
						||
| 
								 | 
							
											 * Multimap supports quite a lot of decluttering options such as whether
							 | 
						||
| 
								 | 
							
											 * to use an accurate of fast declutter algorithm and what icon to use to
							 | 
						||
| 
								 | 
							
											 * represent a cluster. Using all this would mean abstracting all the enums
							 | 
						||
| 
								 | 
							
											 * etc so we're only implementing the group name function at the moment.
							 | 
						||
| 
								 | 
							
											 */
							 | 
						||
| 
								 | 
							
											map.declutterGroup(opts.groupName);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										//	case 'mapquest':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										//	case 'map24':
							 | 
						||
| 
								 | 
							
										//
							 | 
						||
| 
								 | 
							
										//	  break;
							 | 
						||
| 
								 | 
							
										case '  dummy':
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											if(this.debug) {
							 | 
						||
| 
								 | 
							
												alert(this.api + ' not supported by Mapstraction.declutterMarkers');
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Add a polyline to the map
							 | 
						||
| 
								 | 
							
								 * @param {Polyline} polyline The Polyline to add to the map
							 | 
						||
| 
								 | 
							
								 * @param {Boolean} old If true replaces an existing Polyline
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addPolyline = function(polyline, old) {
							 | 
						||
| 
								 | 
							
									polyline.api = this.api;
							 | 
						||
| 
								 | 
							
									polyline.map = this.maps[this.api];
							 | 
						||
| 
								 | 
							
									var propPoly = this.invoker.go('addPolyline', arguments);
							 | 
						||
| 
								 | 
							
									polyline.setChild(propPoly);
							 | 
						||
| 
								 | 
							
									if(!old) {
							 | 
						||
| 
								 | 
							
										this.polylines.push(polyline);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									this.polylineAdded.fire({'polyline': polyline});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Private remove implementation
							 | 
						||
| 
								 | 
							
								var removePolylineImpl = function(polyline) {
							 | 
						||
| 
								 | 
							
									this.invoker.go('removePolyline', arguments);
							 | 
						||
| 
								 | 
							
									polyline.onmap = false;
							 | 
						||
| 
								 | 
							
									this.polylineRemoved.fire({'polyline': polyline});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Remove the polyline from the map
							 | 
						||
| 
								 | 
							
								 * @param {Polyline} polyline The Polyline to remove from the map
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.removePolyline = function(polyline) {
							 | 
						||
| 
								 | 
							
									var current_polyline;
							 | 
						||
| 
								 | 
							
									for(var i = 0; i < this.polylines.length; i++){
							 | 
						||
| 
								 | 
							
										current_polyline = this.polylines[i];
							 | 
						||
| 
								 | 
							
										if(polyline == current_polyline) {
							 | 
						||
| 
								 | 
							
											this.polylines.splice(i, 1);
							 | 
						||
| 
								 | 
							
											removePolylineImpl.call(this, polyline);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Removes all polylines from the map
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.removeAllPolylines = function() {
							 | 
						||
| 
								 | 
							
									var current_polyline;
							 | 
						||
| 
								 | 
							
									while(this.polylines.length > 0) {
							 | 
						||
| 
								 | 
							
										current_polyline = this.polylines.pop();
							 | 
						||
| 
								 | 
							
										removePolylineImpl.call(this, current_polyline);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * autoCenterAndZoom sets the center and zoom of the map to the smallest bounding box
							 | 
						||
| 
								 | 
							
								 * containing all markers
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.autoCenterAndZoom = function() {
							 | 
						||
| 
								 | 
							
									var lat_max = -90;
							 | 
						||
| 
								 | 
							
									var lat_min = 90;
							 | 
						||
| 
								 | 
							
									var lon_max = -180;
							 | 
						||
| 
								 | 
							
									var lon_min = 180;
							 | 
						||
| 
								 | 
							
									var lat, lon;
							 | 
						||
| 
								 | 
							
									var checkMinMax = function(){
							 | 
						||
| 
								 | 
							
										if (lat > lat_max) {
							 | 
						||
| 
								 | 
							
											lat_max = lat;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (lat < lat_min) {
							 | 
						||
| 
								 | 
							
											lat_min = lat;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (lon > lon_max) {
							 | 
						||
| 
								 | 
							
											lon_max = lon;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (lon < lon_min) {
							 | 
						||
| 
								 | 
							
											lon_min = lon;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									for (var i = 0; i < this.markers.length; i++) {
							 | 
						||
| 
								 | 
							
										lat = this.markers[i].location.lat;
							 | 
						||
| 
								 | 
							
										lon = this.markers[i].location.lon;
							 | 
						||
| 
								 | 
							
										checkMinMax();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for(i = 0; i < this.polylines.length; i++) {
							 | 
						||
| 
								 | 
							
										for (var j = 0; j < this.polylines[i].points.length; j++) {
							 | 
						||
| 
								 | 
							
											lat = this.polylines[i].points[j].lat;
							 | 
						||
| 
								 | 
							
											lon = this.polylines[i].points[j].lon;
							 | 
						||
| 
								 | 
							
											checkMinMax();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									this.setBounds( new BoundingBox(lat_min, lon_min, lat_max, lon_max) );
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * centerAndZoomOnPoints sets the center and zoom of the map from an array of points
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This is useful if you don't want to have to add markers to the map
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.centerAndZoomOnPoints = function(points) {
							 | 
						||
| 
								 | 
							
									var bounds = new BoundingBox(points[0].lat,points[0].lon,points[0].lat,points[0].lon);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (var i=1, len = points.length ; i<len; i++) {
							 | 
						||
| 
								 | 
							
										bounds.extend(points[i]);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.setBounds(bounds);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Sets the center and zoom of the map to the smallest bounding box
							 | 
						||
| 
								 | 
							
								 * containing all visible markers and polylines
							 | 
						||
| 
								 | 
							
								 * will only include markers and polylines with an attribute of "visible"
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.visibleCenterAndZoom = function() {
							 | 
						||
| 
								 | 
							
									var lat_max = -90;
							 | 
						||
| 
								 | 
							
									var lat_min = 90;
							 | 
						||
| 
								 | 
							
									var lon_max = -180;
							 | 
						||
| 
								 | 
							
									var lon_min = 180;
							 | 
						||
| 
								 | 
							
									var lat, lon;
							 | 
						||
| 
								 | 
							
									var checkMinMax = function(){
							 | 
						||
| 
								 | 
							
										if (lat > lat_max) {
							 | 
						||
| 
								 | 
							
											lat_max = lat;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (lat < lat_min) {
							 | 
						||
| 
								 | 
							
											lat_min = lat;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (lon > lon_max) {
							 | 
						||
| 
								 | 
							
											lon_max = lon;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (lon < lon_min) {
							 | 
						||
| 
								 | 
							
											lon_min = lon;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									for (var i=0; i<this.markers.length; i++) {
							 | 
						||
| 
								 | 
							
										if (this.markers[i].getAttribute("visible")) {
							 | 
						||
| 
								 | 
							
											lat = this.markers[i].location.lat;
							 | 
						||
| 
								 | 
							
											lon = this.markers[i].location.lon;
							 | 
						||
| 
								 | 
							
											checkMinMax();
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (i=0; i<this.polylines.length; i++){
							 | 
						||
| 
								 | 
							
										if (this.polylines[i].getAttribute("visible")) {
							 | 
						||
| 
								 | 
							
											for (j=0; j<this.polylines[i].points.length; j++) {
							 | 
						||
| 
								 | 
							
												lat = this.polylines[i].points[j].lat;
							 | 
						||
| 
								 | 
							
												lon = this.polylines[i].points[j].lon;
							 | 
						||
| 
								 | 
							
												checkMinMax();
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.setBounds(new BoundingBox(lat_min, lon_min, lat_max, lon_max));
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Automatically sets center and zoom level to show all polylines
							 | 
						||
| 
								 | 
							
								 * Takes into account radious of polyline
							 | 
						||
| 
								 | 
							
								 * @param {Int} radius
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.polylineCenterAndZoom = function(radius) {
							 | 
						||
| 
								 | 
							
									var lat_max = -90;
							 | 
						||
| 
								 | 
							
									var lat_min = 90;
							 | 
						||
| 
								 | 
							
									var lon_max = -180;
							 | 
						||
| 
								 | 
							
									var lon_min = 180;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (var i=0; i < mapstraction.polylines.length; i++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for (var j=0; j<mapstraction.polylines[i].points.length; j++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											lat = mapstraction.polylines[i].points[j].lat;
							 | 
						||
| 
								 | 
							
											lon = mapstraction.polylines[i].points[j].lon;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											latConv = lonConv = radius;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if (radius > 0)
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
												latConv = (radius / mapstraction.polylines[i].points[j].latConv());
							 | 
						||
| 
								 | 
							
												lonConv = (radius / mapstraction.polylines[i].points[j].lonConv());
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ((lat + latConv) > lat_max) {
							 | 
						||
| 
								 | 
							
												lat_max = (lat + latConv);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if ((lat - latConv) < lat_min) {
							 | 
						||
| 
								 | 
							
												lat_min = (lat - latConv);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if ((lon + lonConv) > lon_max) {
							 | 
						||
| 
								 | 
							
												lon_max = (lon + lonConv);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											if ((lon - lonConv) < lon_min) {
							 | 
						||
| 
								 | 
							
												lon_min = (lon - lonConv);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									this.setBounds(new BoundingBox(lat_min, lon_min, lat_max, lon_max));
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addImageOverlay layers an georeferenced image over the map
							 | 
						||
| 
								 | 
							
								 * @param {id} unique DOM identifier
							 | 
						||
| 
								 | 
							
								 * @param {src} url of image
							 | 
						||
| 
								 | 
							
								 * @param {opacity} opacity 0-100
							 | 
						||
| 
								 | 
							
								 * @param {west} west boundary
							 | 
						||
| 
								 | 
							
								 * @param {south} south boundary
							 | 
						||
| 
								 | 
							
								 * @param {east} east boundary
							 | 
						||
| 
								 | 
							
								 * @param {north} north boundary
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addImageOverlay = function(id, src, opacity, west, south, east, north) {
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var b = document.createElement("img");
							 | 
						||
| 
								 | 
							
									b.style.display = 'block';
							 | 
						||
| 
								 | 
							
									b.setAttribute('id',id);
							 | 
						||
| 
								 | 
							
									b.setAttribute('src',src);
							 | 
						||
| 
								 | 
							
									b.style.position = 'absolute';
							 | 
						||
| 
								 | 
							
									b.style.zIndex = 1;
							 | 
						||
| 
								 | 
							
									b.setAttribute('west',west);
							 | 
						||
| 
								 | 
							
									b.setAttribute('south',south);
							 | 
						||
| 
								 | 
							
									b.setAttribute('east',east);
							 | 
						||
| 
								 | 
							
									b.setAttribute('north',north);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									var oContext = {
							 | 
						||
| 
								 | 
							
										imgElm: b
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									this.invoker.go('addImageOverlay', arguments, { context: oContext });
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.setImageOpacity = function(id, opacity) {
							 | 
						||
| 
								 | 
							
									if (opacity < 0) {
							 | 
						||
| 
								 | 
							
										opacity = 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if (opacity >= 100) {
							 | 
						||
| 
								 | 
							
										opacity = 100;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									var c = opacity / 100;
							 | 
						||
| 
								 | 
							
									var d = document.getElementById(id);
							 | 
						||
| 
								 | 
							
									if(typeof(d.style.filter)=='string'){
							 | 
						||
| 
								 | 
							
										d.style.filter='alpha(opacity:'+opacity+')';
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(typeof(d.style.KHTMLOpacity)=='string'){
							 | 
						||
| 
								 | 
							
										d.style.KHTMLOpacity=c;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(typeof(d.style.MozOpacity)=='string'){
							 | 
						||
| 
								 | 
							
										d.style.MozOpacity=c;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(typeof(d.style.opacity)=='string'){
							 | 
						||
| 
								 | 
							
										d.style.opacity=c;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.setImagePosition = function(id) {
							 | 
						||
| 
								 | 
							
									var imgElement = document.getElementById(id);
							 | 
						||
| 
								 | 
							
									var oContext = {
							 | 
						||
| 
								 | 
							
										latLng: { 
							 | 
						||
| 
								 | 
							
											top: imgElement.getAttribute('north'),
							 | 
						||
| 
								 | 
							
											left: imgElement.getAttribute('west'),
							 | 
						||
| 
								 | 
							
											bottom: imgElement.getAttribute('south'),
							 | 
						||
| 
								 | 
							
											right: imgElement.getAttribute('east')
							 | 
						||
| 
								 | 
							
										},
							 | 
						||
| 
								 | 
							
										pixels: { top: 0, right: 0, bottom: 0, left: 0 }
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									this.invoker.go('setImagePosition', arguments, { context: oContext });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									imgElement.style.top = oContext.pixels.top.toString() + 'px';
							 | 
						||
| 
								 | 
							
									imgElement.style.left = oContext.pixels.left.toString() + 'px';
							 | 
						||
| 
								 | 
							
									imgElement.style.width = (oContext.pixels.right - oContext.pixels.left).toString() + 'px';
							 | 
						||
| 
								 | 
							
									imgElement.style.height = (oContext.pixels.bottom - oContext.pixels.top).toString() + 'px';
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addJSON = function(json) {
							 | 
						||
| 
								 | 
							
									var features;
							 | 
						||
| 
								 | 
							
									if (typeof(json) == "string") {
							 | 
						||
| 
								 | 
							
										features = eval('(' + json + ')');
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										features = json;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									features = features.features;
							 | 
						||
| 
								 | 
							
									var map = this.maps[this.api];
							 | 
						||
| 
								 | 
							
									var html = "";
							 | 
						||
| 
								 | 
							
									var item;
							 | 
						||
| 
								 | 
							
									var polyline;
							 | 
						||
| 
								 | 
							
									var marker;
							 | 
						||
| 
								 | 
							
									var markers = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(features.type == "FeatureCollection") {
							 | 
						||
| 
								 | 
							
										this.addJSON(features.features);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (var i = 0; i < features.length; i++) {
							 | 
						||
| 
								 | 
							
										item = features[i];
							 | 
						||
| 
								 | 
							
										switch(item.geometry.type) {
							 | 
						||
| 
								 | 
							
											case "Point":
							 | 
						||
| 
								 | 
							
												html = "<strong>" + item.title + "</strong><p>" + item.description + "</p>";
							 | 
						||
| 
								 | 
							
												marker = new Marker(new LatLonPoint(item.geometry.coordinates[1],item.geometry.coordinates[0]));
							 | 
						||
| 
								 | 
							
												markers.push(marker);
							 | 
						||
| 
								 | 
							
												this.addMarkerWithData(marker,{
							 | 
						||
| 
								 | 
							
													infoBubble : html,
							 | 
						||
| 
								 | 
							
													label : item.title,
							 | 
						||
| 
								 | 
							
													date : "new Date(\""+item.date+"\")",
							 | 
						||
| 
								 | 
							
													iconShadow : item.icon_shadow,
							 | 
						||
| 
								 | 
							
													marker : item.id,
							 | 
						||
| 
								 | 
							
													iconShadowSize : item.icon_shadow_size,
							 | 
						||
| 
								 | 
							
													icon : "http://boston.openguides.org/markers/AQUA.png",
							 | 
						||
| 
								 | 
							
													iconSize : item.icon_size,
							 | 
						||
| 
								 | 
							
													category : item.source_id,
							 | 
						||
| 
								 | 
							
													draggable : false,
							 | 
						||
| 
								 | 
							
													hover : false
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case "Polygon":
							 | 
						||
| 
								 | 
							
												var points = [];
							 | 
						||
| 
								 | 
							
												polyline = new Polyline(points);
							 | 
						||
| 
								 | 
							
												mapstraction.addPolylineWithData(polyline,{
							 | 
						||
| 
								 | 
							
													fillColor : item.poly_color,
							 | 
						||
| 
								 | 
							
													date : "new Date(\""+item.date+"\")",
							 | 
						||
| 
								 | 
							
													category : item.source_id,
							 | 
						||
| 
								 | 
							
													width : item.line_width,
							 | 
						||
| 
								 | 
							
													opacity : item.line_opacity,
							 | 
						||
| 
								 | 
							
													color : item.line_color,
							 | 
						||
| 
								 | 
							
													polygon : true
							 | 
						||
| 
								 | 
							
												});
							 | 
						||
| 
								 | 
							
												markers.push(polyline);
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
										// console.log("Geometry: " + features.items[i].geometry.type);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return markers;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Adds a Tile Layer to the map
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Requires providing a parameterized tile url. Use {Z}, {X}, and {Y} to specify where the parameters
							 | 
						||
| 
								 | 
							
								 *  should go in the URL.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * For example, the OpenStreetMap tiles are:
							 | 
						||
| 
								 | 
							
								 *  m.addTileLayer("http://tile.openstreetmap.org/{Z}/{X}/{Y}.png", 1.0, "OSM", 1, 19, true);
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param {tile_url} template url of the tiles.
							 | 
						||
| 
								 | 
							
								 * @param {opacity} opacity of the tile layer - 0 is transparent, 1 is opaque. (default=0.6)
							 | 
						||
| 
								 | 
							
								 * @param {copyright_text} copyright text to use for the tile layer. (default=Mapstraction)
							 | 
						||
| 
								 | 
							
								 * @param {min_zoom} Minimum (furtherest out) zoom level that tiles are available (default=1)
							 | 
						||
| 
								 | 
							
								 * @param {max_zoom} Maximum (closest) zoom level that the tiles are available (default=18)
							 | 
						||
| 
								 | 
							
								 * @param {map_type} Should the tile layer be a selectable map type in the layers palette (default=false)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addTileLayer = function(tile_url, opacity, copyright_text, min_zoom, max_zoom, map_type) {
							 | 
						||
| 
								 | 
							
									if(!tile_url) {
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									this.tileLayers = this.tileLayers || [];	
							 | 
						||
| 
								 | 
							
									opacity = opacity || 0.6;
							 | 
						||
| 
								 | 
							
									copyright_text = copyright_text || "Mapstraction";
							 | 
						||
| 
								 | 
							
									min_zoom = min_zoom || 1;
							 | 
						||
| 
								 | 
							
									max_zoom = max_zoom || 18;
							 | 
						||
| 
								 | 
							
									map_type = map_type || false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return this.invoker.go('addTileLayer', [ tile_url, opacity, copyright_text, min_zoom, max_zoom, map_type] );
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addFilter adds a marker filter
							 | 
						||
| 
								 | 
							
								 * @param {field} name of attribute to filter on
							 | 
						||
| 
								 | 
							
								 * @param {operator} presently only "ge" or "le"
							 | 
						||
| 
								 | 
							
								 * @param {value} the value to compare against
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.addFilter = function(field, operator, value) {
							 | 
						||
| 
								 | 
							
									if (!this.filters) {
							 | 
						||
| 
								 | 
							
										this.filters = [];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									this.filters.push( [field, operator, value] );
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Remove the specified filter
							 | 
						||
| 
								 | 
							
								 * @param {Object} field
							 | 
						||
| 
								 | 
							
								 * @param {Object} operator
							 | 
						||
| 
								 | 
							
								 * @param {Object} value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.removeFilter = function(field, operator, value) {
							 | 
						||
| 
								 | 
							
									if (!this.filters) {
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var del;
							 | 
						||
| 
								 | 
							
									for (var f=0; f<this.filters.length; f++) {
							 | 
						||
| 
								 | 
							
										if (this.filters[f][0] == field &&
							 | 
						||
| 
								 | 
							
											(! operator || (this.filters[f][1] == operator && this.filters[f][2] == value))) {
							 | 
						||
| 
								 | 
							
											this.filters.splice(f,1);
							 | 
						||
| 
								 | 
							
											f--; //array size decreased
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Delete the current filter if present; otherwise add it
							 | 
						||
| 
								 | 
							
								 * @param {Object} field
							 | 
						||
| 
								 | 
							
								 * @param {Object} operator
							 | 
						||
| 
								 | 
							
								 * @param {Object} value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.toggleFilter = function(field, operator, value) {
							 | 
						||
| 
								 | 
							
									if (!this.filters) {
							 | 
						||
| 
								 | 
							
										this.filters = [];
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var found = false;
							 | 
						||
| 
								 | 
							
									for (var f = 0; f < this.filters.length; f++) {
							 | 
						||
| 
								 | 
							
										if (this.filters[f][0] == field && this.filters[f][1] == operator && this.filters[f][2] == value) {
							 | 
						||
| 
								 | 
							
											this.filters.splice(f,1);
							 | 
						||
| 
								 | 
							
											f--; //array size decreased
							 | 
						||
| 
								 | 
							
											found = true;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (! found) {
							 | 
						||
| 
								 | 
							
										this.addFilter(field, operator, value);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * removeAllFilters
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.removeAllFilters = function() {
							 | 
						||
| 
								 | 
							
									this.filters = [];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * doFilter executes all filters added since last call
							 | 
						||
| 
								 | 
							
								 * Now supports a callback function for when a marker is shown or hidden
							 | 
						||
| 
								 | 
							
								 * @param {Function} showCallback
							 | 
						||
| 
								 | 
							
								 * @param {Function} hideCallback
							 | 
						||
| 
								 | 
							
								 * @returns {Int} count of visible markers
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.doFilter = function(showCallback, hideCallback) {
							 | 
						||
| 
								 | 
							
									var map = this.maps[this.api];
							 | 
						||
| 
								 | 
							
									var visibleCount = 0;
							 | 
						||
| 
								 | 
							
									var f;
							 | 
						||
| 
								 | 
							
									if (this.filters) {
							 | 
						||
| 
								 | 
							
										switch (this.api) {
							 | 
						||
| 
								 | 
							
											case 'multimap':
							 | 
						||
| 
								 | 
							
												/* TODO polylines aren't filtered in multimap */
							 | 
						||
| 
								 | 
							
												var mmfilters = [];
							 | 
						||
| 
								 | 
							
												for (f=0; f<this.filters.length; f++) {
							 | 
						||
| 
								 | 
							
													mmfilters.push( new MMSearchFilter( this.filters[f][0], this.filters[f][1], this.filters[f][2] ));
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												map.setMarkerFilters( mmfilters );
							 | 
						||
| 
								 | 
							
												map.redrawMap();
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											case '  dummy':
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
											default:
							 | 
						||
| 
								 | 
							
												var vis;
							 | 
						||
| 
								 | 
							
												for (var m=0; m<this.markers.length; m++) {
							 | 
						||
| 
								 | 
							
													vis = true;
							 | 
						||
| 
								 | 
							
													for (f = 0; f < this.filters.length; f++) {
							 | 
						||
| 
								 | 
							
														if (! this.applyFilter(this.markers[m], this.filters[f])) {
							 | 
						||
| 
								 | 
							
															vis = false;
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													if (vis) {
							 | 
						||
| 
								 | 
							
														visibleCount ++;
							 | 
						||
| 
								 | 
							
														if (showCallback){
							 | 
						||
| 
								 | 
							
															showCallback(this.markers[m]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else {
							 | 
						||
| 
								 | 
							
															this.markers[m].show();
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													} 
							 | 
						||
| 
								 | 
							
													else { 
							 | 
						||
| 
								 | 
							
														if (hideCallback){
							 | 
						||
| 
								 | 
							
															hideCallback(this.markers[m]);
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
														else {
							 | 
						||
| 
								 | 
							
															this.markers[m].hide();
							 | 
						||
| 
								 | 
							
														}
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
													this.markers[m].setAttribute("visible", vis);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
												break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return visibleCount;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.applyFilter = function(o, f) {
							 | 
						||
| 
								 | 
							
									var vis = true;
							 | 
						||
| 
								 | 
							
									switch (f[1]) {
							 | 
						||
| 
								 | 
							
										case 'ge':
							 | 
						||
| 
								 | 
							
											if (o.getAttribute( f[0] ) < f[2]) {
							 | 
						||
| 
								 | 
							
												vis = false;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										case 'le':
							 | 
						||
| 
								 | 
							
											if (o.getAttribute( f[0] ) > f[2]) {
							 | 
						||
| 
								 | 
							
												vis = false;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										case 'eq':
							 | 
						||
| 
								 | 
							
											if (o.getAttribute( f[0] ) == f[2]) {
							 | 
						||
| 
								 | 
							
												vis = false;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return vis;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * getAttributeExtremes returns the minimum/maximum of "field" from all markers
							 | 
						||
| 
								 | 
							
								 * @param {field} name of "field" to query
							 | 
						||
| 
								 | 
							
								 * @returns {array} of minimum/maximum
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.getAttributeExtremes = function(field) {
							 | 
						||
| 
								 | 
							
									var min;
							 | 
						||
| 
								 | 
							
									var max;
							 | 
						||
| 
								 | 
							
									for (var m=0; m<this.markers.length; m++) {
							 | 
						||
| 
								 | 
							
										if (! min || min > this.markers[m].getAttribute(field)) {
							 | 
						||
| 
								 | 
							
											min = this.markers[m].getAttribute(field);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (! max || max < this.markers[m].getAttribute(field)) {
							 | 
						||
| 
								 | 
							
											max = this.markers[m].getAttribute(field);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									for (var p=0; m<this.polylines.length; m++) {
							 | 
						||
| 
								 | 
							
										if (! min || min > this.polylines[p].getAttribute(field)) {
							 | 
						||
| 
								 | 
							
											min = this.polylines[p].getAttribute(field);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										if (! max || max < this.polylines[p].getAttribute(field)) {
							 | 
						||
| 
								 | 
							
											max = this.polylines[p].getAttribute(field);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return [min, max];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * getMap returns the native map object that mapstraction is talking to
							 | 
						||
| 
								 | 
							
								 * @returns the native map object mapstraction is using
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Mapstraction.prototype.getMap = function() {
							 | 
						||
| 
								 | 
							
									// FIXME in an ideal world this shouldn't exist right?
							 | 
						||
| 
								 | 
							
									return this.maps[this.api];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//   LatLonPoint
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								/////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * LatLonPoint is a point containing a latitude and longitude with helper methods
							 | 
						||
| 
								 | 
							
								 * @name mxn.LatLonPoint
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {double} lat is the latitude
							 | 
						||
| 
								 | 
							
								 * @param {double} lon is the longitude
							 | 
						||
| 
								 | 
							
								 * @exports LatLonPoint as mxn.LatLonPoint
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var LatLonPoint = mxn.LatLonPoint = function(lat, lon) {
							 | 
						||
| 
								 | 
							
									// TODO error if undefined?
							 | 
						||
| 
								 | 
							
									//  if (lat == undefined) alert('undefined lat');
							 | 
						||
| 
								 | 
							
									//  if (lon == undefined) alert('undefined lon');
							 | 
						||
| 
								 | 
							
									this.lat = lat;
							 | 
						||
| 
								 | 
							
									this.lon = lon;
							 | 
						||
| 
								 | 
							
									this.lng = lon; // lets be lon/lng agnostic
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									this.invoker = new mxn.Invoker(this, 'LatLonPoint');		
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mxn.addProxyMethods(LatLonPoint, [ 
							 | 
						||
| 
								 | 
							
									'fromProprietary', 'toProprietary'
							 | 
						||
| 
								 | 
							
								], true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * toString returns a string represntation of a point
							 | 
						||
| 
								 | 
							
								 * @returns a string like '51.23, -0.123'
							 | 
						||
| 
								 | 
							
								 * @type String
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								LatLonPoint.prototype.toString = function() {
							 | 
						||
| 
								 | 
							
									return this.lat + ', ' + this.lon;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * distance returns the distance in kilometers between two points
							 | 
						||
| 
								 | 
							
								 * @param {LatLonPoint} otherPoint The other point to measure the distance from to this one
							 | 
						||
| 
								 | 
							
								 * @returns the distance between the points in kilometers
							 | 
						||
| 
								 | 
							
								 * @type double
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								LatLonPoint.prototype.distance = function(otherPoint) {
							 | 
						||
| 
								 | 
							
									// Uses Haversine formula from http://www.movable-type.co.uk
							 | 
						||
| 
								 | 
							
									var rads = Math.PI / 180;
							 | 
						||
| 
								 | 
							
									var diffLat = (this.lat-otherPoint.lat) * rads;
							 | 
						||
| 
								 | 
							
									var diffLon = (this.lon-otherPoint.lon) * rads; 
							 | 
						||
| 
								 | 
							
									var a = Math.sin(diffLat / 2) * Math.sin(diffLat / 2) +
							 | 
						||
| 
								 | 
							
										Math.cos(this.lat*rads) * Math.cos(otherPoint.lat*rads) * 
							 | 
						||
| 
								 | 
							
										Math.sin(diffLon/2) * Math.sin(diffLon/2); 
							 | 
						||
| 
								 | 
							
									return 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) * 6371; // Earth's mean radius in km
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * equals tests if this point is the same as some other one
							 | 
						||
| 
								 | 
							
								 * @param {LatLonPoint} otherPoint The other point to test with
							 | 
						||
| 
								 | 
							
								 * @returns true or false
							 | 
						||
| 
								 | 
							
								 * @type boolean
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								LatLonPoint.prototype.equals = function(otherPoint) {
							 | 
						||
| 
								 | 
							
									return this.lat == otherPoint.lat && this.lon == otherPoint.lon;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Returns latitude conversion based on current projection
							 | 
						||
| 
								 | 
							
								 * @returns {Float} conversion
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								LatLonPoint.prototype.latConv = function() {
							 | 
						||
| 
								 | 
							
									return this.distance(new LatLonPoint(this.lat + 0.1, this.lon))*10;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Returns longitude conversion based on current projection
							 | 
						||
| 
								 | 
							
								 * @returns {Float} conversion
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								LatLonPoint.prototype.lonConv = function() {
							 | 
						||
| 
								 | 
							
									return this.distance(new LatLonPoint(this.lat, this.lon + 0.1))*10;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  BoundingBox
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * BoundingBox creates a new bounding box object
							 | 
						||
| 
								 | 
							
								 * @name mxn.BoundingBox
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {double} swlat the latitude of the south-west point
							 | 
						||
| 
								 | 
							
								 * @param {double} swlon the longitude of the south-west point
							 | 
						||
| 
								 | 
							
								 * @param {double} nelat the latitude of the north-east point
							 | 
						||
| 
								 | 
							
								 * @param {double} nelon the longitude of the north-east point
							 | 
						||
| 
								 | 
							
								 * @exports BoundingBox as mxn.BoundingBox
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var BoundingBox = mxn.BoundingBox = function(swlat, swlon, nelat, nelon) {
							 | 
						||
| 
								 | 
							
									//FIXME throw error if box bigger than world
							 | 
						||
| 
								 | 
							
									//alert('new bbox ' + swlat + ',' +  swlon + ',' +  nelat + ',' + nelon);
							 | 
						||
| 
								 | 
							
									this.sw = new LatLonPoint(swlat, swlon);
							 | 
						||
| 
								 | 
							
									this.ne = new LatLonPoint(nelat, nelon);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * getSouthWest returns a LatLonPoint of the south-west point of the bounding box
							 | 
						||
| 
								 | 
							
								 * @returns the south-west point of the bounding box
							 | 
						||
| 
								 | 
							
								 * @type LatLonPoint
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BoundingBox.prototype.getSouthWest = function() {
							 | 
						||
| 
								 | 
							
									return this.sw;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * getNorthEast returns a LatLonPoint of the north-east point of the bounding box
							 | 
						||
| 
								 | 
							
								 * @returns the north-east point of the bounding box
							 | 
						||
| 
								 | 
							
								 * @type LatLonPoint
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BoundingBox.prototype.getNorthEast = function() {
							 | 
						||
| 
								 | 
							
									return this.ne;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * isEmpty finds if this bounding box has zero area
							 | 
						||
| 
								 | 
							
								 * @returns whether the north-east and south-west points of the bounding box are the same point
							 | 
						||
| 
								 | 
							
								 * @type boolean
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BoundingBox.prototype.isEmpty = function() {
							 | 
						||
| 
								 | 
							
									return this.ne == this.sw; // is this right? FIXME
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * contains finds whether a given point is within a bounding box
							 | 
						||
| 
								 | 
							
								 * @param {LatLonPoint} point the point to test with
							 | 
						||
| 
								 | 
							
								 * @returns whether point is within this bounding box
							 | 
						||
| 
								 | 
							
								 * @type boolean
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BoundingBox.prototype.contains = function(point){
							 | 
						||
| 
								 | 
							
									return point.lat >= this.sw.lat && point.lat <= this.ne.lat && point.lon >= this.sw.lon && point.lon <= this.ne.lon;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * toSpan returns a LatLonPoint with the lat and lon as the height and width of the bounding box
							 | 
						||
| 
								 | 
							
								 * @returns a LatLonPoint containing the height and width of this bounding box
							 | 
						||
| 
								 | 
							
								 * @type LatLonPoint
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BoundingBox.prototype.toSpan = function() {
							 | 
						||
| 
								 | 
							
									return new LatLonPoint( Math.abs(this.sw.lat - this.ne.lat), Math.abs(this.sw.lon - this.ne.lon) );
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * extend extends the bounding box to include the new point
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								BoundingBox.prototype.extend = function(point) {
							 | 
						||
| 
								 | 
							
									if(this.sw.lat > point.lat) {
							 | 
						||
| 
								 | 
							
										this.sw.lat = point.lat;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(this.sw.lon > point.lon) {
							 | 
						||
| 
								 | 
							
										this.sw.lon = point.lon;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(this.ne.lat < point.lat) {
							 | 
						||
| 
								 | 
							
										this.ne.lat = point.lat;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(this.ne.lon < point.lon) {
							 | 
						||
| 
								 | 
							
										this.ne.lon = point.lon;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//////////////////////////////
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//  Marker
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								///////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Marker create's a new marker pin
							 | 
						||
| 
								 | 
							
								 * @name mxn.Marker
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {LatLonPoint} point the point on the map where the marker should go
							 | 
						||
| 
								 | 
							
								 * @exports Marker as mxn.Marker
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var Marker = mxn.Marker = function(point) {
							 | 
						||
| 
								 | 
							
									this.api = null;
							 | 
						||
| 
								 | 
							
									this.location = point;
							 | 
						||
| 
								 | 
							
									this.onmap = false;
							 | 
						||
| 
								 | 
							
									this.proprietary_marker = false;
							 | 
						||
| 
								 | 
							
									this.attributes = [];
							 | 
						||
| 
								 | 
							
									this.invoker = new mxn.Invoker(this, 'Marker', function(){return this.api;});
							 | 
						||
| 
								 | 
							
									mxn.addEvents(this, [ 
							 | 
						||
| 
								 | 
							
										'openInfoBubble',	// Info bubble opened
							 | 
						||
| 
								 | 
							
										'closeInfoBubble', 	// Info bubble closed
							 | 
						||
| 
								 | 
							
										'click'				// Marker clicked
							 | 
						||
| 
								 | 
							
									]);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mxn.addProxyMethods(Marker, [ 
							 | 
						||
| 
								 | 
							
									'fromProprietary',
							 | 
						||
| 
								 | 
							
									'hide',
							 | 
						||
| 
								 | 
							
									'openBubble',
							 | 
						||
| 
								 | 
							
									'show',
							 | 
						||
| 
								 | 
							
									'toProprietary',
							 | 
						||
| 
								 | 
							
									'update'
							 | 
						||
| 
								 | 
							
								]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Marker.prototype.setChild = function(some_proprietary_marker) {
							 | 
						||
| 
								 | 
							
									this.proprietary_marker = some_proprietary_marker;
							 | 
						||
| 
								 | 
							
									some_proprietary_marker.mapstraction_marker = this;
							 | 
						||
| 
								 | 
							
									this.onmap = true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Marker.prototype.setLabel = function(labelText) {
							 | 
						||
| 
								 | 
							
									this.labelText = labelText;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addData conviniently set a hash of options on a marker
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.addData = function(options){
							 | 
						||
| 
								 | 
							
									for(var sOptKey in options) {
							 | 
						||
| 
								 | 
							
										if(options.hasOwnProperty(sOptKey)){
							 | 
						||
| 
								 | 
							
											switch(sOptKey) {
							 | 
						||
| 
								 | 
							
												case 'label':
							 | 
						||
| 
								 | 
							
													this.setLabel(options.label);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'infoBubble':
							 | 
						||
| 
								 | 
							
													this.setInfoBubble(options.infoBubble);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'icon':
							 | 
						||
| 
								 | 
							
													if(options.iconSize && options.iconAnchor) {
							 | 
						||
| 
								 | 
							
														this.setIcon(options.icon, options.iconSize, options.iconAnchor);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else if(options.iconSize) {
							 | 
						||
| 
								 | 
							
														this.setIcon(options.icon, options.iconSize);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else {
							 | 
						||
| 
								 | 
							
														this.setIcon(options.icon);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'iconShadow':
							 | 
						||
| 
								 | 
							
													if(options.iconShadowSize) {
							 | 
						||
| 
								 | 
							
														this.setShadowIcon(options.iconShadow, [ options.iconShadowSize[0], options.iconShadowSize[1] ]);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													else {
							 | 
						||
| 
								 | 
							
														this.setIcon(options.iconShadow);
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'infoDiv':
							 | 
						||
| 
								 | 
							
													this.setInfoDiv(options.infoDiv[0],options.infoDiv[1]);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'draggable':
							 | 
						||
| 
								 | 
							
													this.setDraggable(options.draggable);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'hover':
							 | 
						||
| 
								 | 
							
													this.setHover(options.hover);
							 | 
						||
| 
								 | 
							
													this.setHoverIcon(options.hoverIcon);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'hoverIcon':
							 | 
						||
| 
								 | 
							
													this.setHoverIcon(options.hoverIcon);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'openBubble':
							 | 
						||
| 
								 | 
							
													this.openBubble();
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'groupName':
							 | 
						||
| 
								 | 
							
													this.setGroupName(options.groupName);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													// don't have a specific action for this bit of
							 | 
						||
| 
								 | 
							
													// data so set a named attribute
							 | 
						||
| 
								 | 
							
													this.setAttribute(sOptKey, options[sOptKey]);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setInfoBubble sets the html/text content for a bubble popup for a marker
							 | 
						||
| 
								 | 
							
								 * @param {String} infoBubble the html/text you want displayed
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setInfoBubble = function(infoBubble) {
							 | 
						||
| 
								 | 
							
									this.infoBubble = infoBubble;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setInfoDiv sets the text and the id of the div element where to the information
							 | 
						||
| 
								 | 
							
								 *  useful for putting information in a div outside of the map
							 | 
						||
| 
								 | 
							
								 * @param {String} infoDiv the html/text you want displayed
							 | 
						||
| 
								 | 
							
								 * @param {String} div the element id to use for displaying the text/html
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setInfoDiv = function(infoDiv,div){
							 | 
						||
| 
								 | 
							
									this.infoDiv = infoDiv;
							 | 
						||
| 
								 | 
							
									this.div = div;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setIcon sets the icon for a marker
							 | 
						||
| 
								 | 
							
								 * @param {String} iconUrl The URL of the image you want to be the icon
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setIcon = function(iconUrl, iconSize, iconAnchor) {
							 | 
						||
| 
								 | 
							
									this.iconUrl = iconUrl;
							 | 
						||
| 
								 | 
							
									if(iconSize) {
							 | 
						||
| 
								 | 
							
										this.iconSize = iconSize;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if(iconAnchor) {
							 | 
						||
| 
								 | 
							
										this.iconAnchor = iconAnchor;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setIconSize sets the size of the icon for a marker
							 | 
						||
| 
								 | 
							
								 * @param {String} iconSize The array size in pixels of the marker image
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setIconSize = function(iconSize){
							 | 
						||
| 
								 | 
							
									if(iconSize) {
							 | 
						||
| 
								 | 
							
										this.iconSize = iconSize;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setIconAnchor sets the anchor point for a marker
							 | 
						||
| 
								 | 
							
								 * @param {String} iconAnchor The array offset of the anchor point
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setIconAnchor = function(iconAnchor){
							 | 
						||
| 
								 | 
							
									if(iconAnchor) {
							 | 
						||
| 
								 | 
							
										this.iconAnchor = iconAnchor;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setShadowIcon sets the icon for a marker
							 | 
						||
| 
								 | 
							
								 * @param {String} iconUrl The URL of the image you want to be the icon
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setShadowIcon = function(iconShadowUrl, iconShadowSize){
							 | 
						||
| 
								 | 
							
									this.iconShadowUrl = iconShadowUrl;
							 | 
						||
| 
								 | 
							
									if(iconShadowSize) {
							 | 
						||
| 
								 | 
							
										this.iconShadowSize = iconShadowSize;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Marker.prototype.setHoverIcon = function(hoverIconUrl){
							 | 
						||
| 
								 | 
							
									this.hoverIconUrl = hoverIconUrl;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setDraggable sets the draggable state of the marker
							 | 
						||
| 
								 | 
							
								 * @param {Bool} draggable set to true if marker should be draggable by the user
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setDraggable = function(draggable) {
							 | 
						||
| 
								 | 
							
									this.draggable = draggable;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setHover sets that the marker info is displayed on hover
							 | 
						||
| 
								 | 
							
								 * @param {Bool} hover set to true if marker should display info on hover
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setHover = function(hover) {
							 | 
						||
| 
								 | 
							
									this.hover = hover;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Markers are grouped up by this name. declutterGroup makes use of this.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setGroupName = function(sGrpName) {
							 | 
						||
| 
								 | 
							
									this.groupName = sGrpName;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setAttribute: set an arbitrary key/value pair on a marker
							 | 
						||
| 
								 | 
							
								 * @arg(String) key
							 | 
						||
| 
								 | 
							
								 * @arg value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.setAttribute = function(key,value) {
							 | 
						||
| 
								 | 
							
									this.attributes[key] = value;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * getAttribute: gets the value of "key"
							 | 
						||
| 
								 | 
							
								 * @arg(String) key
							 | 
						||
| 
								 | 
							
								 * @returns value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Marker.prototype.getAttribute = function(key) {
							 | 
						||
| 
								 | 
							
									return this.attributes[key];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////
							 | 
						||
| 
								 | 
							
								// Polyline ///
							 | 
						||
| 
								 | 
							
								///////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Instantiates a new Polyline.
							 | 
						||
| 
								 | 
							
								 * @name mxn.Polyline
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @param {Point[]} points Points that make up the Polyline.
							 | 
						||
| 
								 | 
							
								 * @exports Polyline as mxn.Polyline
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var Polyline = mxn.Polyline = function(points) {
							 | 
						||
| 
								 | 
							
									this.api = null;
							 | 
						||
| 
								 | 
							
									this.points = points;
							 | 
						||
| 
								 | 
							
									this.attributes = [];
							 | 
						||
| 
								 | 
							
									this.onmap = false;
							 | 
						||
| 
								 | 
							
									this.proprietary_polyline = false;
							 | 
						||
| 
								 | 
							
									this.pllID = "mspll-"+new Date().getTime()+'-'+(Math.floor(Math.random()*Math.pow(2,16)));
							 | 
						||
| 
								 | 
							
									this.invoker = new mxn.Invoker(this, 'Polyline', function(){return this.api;});
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mxn.addProxyMethods(Polyline, [ 
							 | 
						||
| 
								 | 
							
									'fromProprietary', 
							 | 
						||
| 
								 | 
							
									'hide',
							 | 
						||
| 
								 | 
							
									'show',
							 | 
						||
| 
								 | 
							
									'toProprietary',
							 | 
						||
| 
								 | 
							
									'update'
							 | 
						||
| 
								 | 
							
								]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * addData conviniently set a hash of options on a polyline
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.addData = function(options){
							 | 
						||
| 
								 | 
							
									for(var sOpt in options) {
							 | 
						||
| 
								 | 
							
										if(options.hasOwnProperty(sOpt)){
							 | 
						||
| 
								 | 
							
											switch(sOpt) {
							 | 
						||
| 
								 | 
							
												case 'color':
							 | 
						||
| 
								 | 
							
													this.setColor(options.color);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'width':
							 | 
						||
| 
								 | 
							
													this.setWidth(options.width);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'opacity':
							 | 
						||
| 
								 | 
							
													this.setOpacity(options.opacity);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'closed':
							 | 
						||
| 
								 | 
							
													this.setClosed(options.closed);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												case 'fillColor':
							 | 
						||
| 
								 | 
							
													this.setFillColor(options.fillColor);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												default:
							 | 
						||
| 
								 | 
							
													this.setAttribute(sOpt, options[sOpt]);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setChild = function(some_proprietary_polyline) {
							 | 
						||
| 
								 | 
							
									this.proprietary_polyline = some_proprietary_polyline;
							 | 
						||
| 
								 | 
							
									this.onmap = true;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * in the form: #RRGGBB
							 | 
						||
| 
								 | 
							
								 * Note map24 insists on upper case, so we convert it.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setColor = function(color){
							 | 
						||
| 
								 | 
							
									this.color = (color.length==7 && color[0]=="#") ? color.toUpperCase() : color;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Stroke width of the polyline
							 | 
						||
| 
								 | 
							
								 * @param {Integer} width
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setWidth = function(width){
							 | 
						||
| 
								 | 
							
									this.width = width;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A float between 0.0 and 1.0
							 | 
						||
| 
								 | 
							
								 * @param {Float} opacity
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setOpacity = function(opacity){
							 | 
						||
| 
								 | 
							
									this.opacity = opacity;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Marks the polyline as a closed polygon
							 | 
						||
| 
								 | 
							
								 * @param {Boolean} bClosed
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setClosed = function(bClosed){
							 | 
						||
| 
								 | 
							
									this.closed = bClosed;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Fill color for a closed polyline as HTML color value e.g. #RRGGBB
							 | 
						||
| 
								 | 
							
								 * @param {String} sFillColor HTML color value #RRGGBB
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setFillColor = function(sFillColor) {
							 | 
						||
| 
								 | 
							
									this.fillColor = sFillColor;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * setAttribute: set an arbitrary key/value pair on a polyline
							 | 
						||
| 
								 | 
							
								 * @arg(String) key
							 | 
						||
| 
								 | 
							
								 * @arg value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.setAttribute = function(key,value) {
							 | 
						||
| 
								 | 
							
									this.attributes[key] = value;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * getAttribute: gets the value of "key"
							 | 
						||
| 
								 | 
							
								 * @arg(String) key
							 | 
						||
| 
								 | 
							
								 * @returns value
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.getAttribute = function(key) {
							 | 
						||
| 
								 | 
							
									return this.attributes[key];
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Simplifies a polyline, averaging and reducing the points
							 | 
						||
| 
								 | 
							
								 * @param {Integer} tolerance (1.0 is a good starting point)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Polyline.prototype.simplify = function(tolerance) {
							 | 
						||
| 
								 | 
							
									var reduced = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// First point
							 | 
						||
| 
								 | 
							
									reduced[0] = this.points[0];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var markerPoint = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for (var i = 1; i < this.points.length-1; i++){
							 | 
						||
| 
								 | 
							
										if (this.points[i].distance(this.points[markerPoint]) >= tolerance)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											reduced[reduced.length] = this.points[i];
							 | 
						||
| 
								 | 
							
											markerPoint = i;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Last point
							 | 
						||
| 
								 | 
							
									reduced[reduced.length] = this.points[this.points.length-1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Revert
							 | 
						||
| 
								 | 
							
									this.points = reduced;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////
							 | 
						||
| 
								 | 
							
								// Radius    //
							 | 
						||
| 
								 | 
							
								///////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Creates a new radius object for drawing circles around a point, does a lot of initial calculation to increase load time
							 | 
						||
| 
								 | 
							
								 * @returns a new Radius
							 | 
						||
| 
								 | 
							
								 * @type Radius
							 | 
						||
| 
								 | 
							
								 * @constructor
							 | 
						||
| 
								 | 
							
								 * @classDescription Radius
							 | 
						||
| 
								 | 
							
								 * @param {Object} Center LatLonPoint of the radius
							 | 
						||
| 
								 | 
							
								 * @param {quality} Number of points that comprise the approximated circle (20 is a good starting point)
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								var Radius = mxn.Radius = function(center, quality) {
							 | 
						||
| 
								 | 
							
									this.center = center;
							 | 
						||
| 
								 | 
							
									var latConv = center.latConv();
							 | 
						||
| 
								 | 
							
									var lonConv = center.lonConv();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Create Radian conversion constant
							 | 
						||
| 
								 | 
							
									var rad = Math.PI / 180;
							 | 
						||
| 
								 | 
							
									this.calcs = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(var i = 0; i < 360; i += quality){
							 | 
						||
| 
								 | 
							
									    this.calcs.push([Math.cos(i * rad) / latConv, Math.sin(i * rad) / lonConv]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Returns polyline of a circle around the point based on new radius
							 | 
						||
| 
								 | 
							
								 * @param {Radius} radius
							 | 
						||
| 
								 | 
							
								 * @param {Colour} colour
							 | 
						||
| 
								 | 
							
								 * @returns {Polyline} Polyline
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								Radius.prototype.getPolyline = function(radius, colour) {
							 | 
						||
| 
								 | 
							
								        var points = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(var i = 0; i < this.calcs.length; i++){
							 | 
						||
| 
								 | 
							
										var point = new LatLonPoint(
							 | 
						||
| 
								 | 
							
											this.center.lat + (radius * this.calcs[i][0]),
							 | 
						||
| 
								 | 
							
											this.center.lon + (radius * this.calcs[i][1])
							 | 
						||
| 
								 | 
							
										);
							 | 
						||
| 
								 | 
							
										points.push(point);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Add first point
							 | 
						||
| 
								 | 
							
									points.push(points[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var line = new Polyline(points);
							 | 
						||
| 
								 | 
							
									line.setColor(colour);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return line;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								})();
							 |