1 if (Garmin == undefined) var Garmin = {}; 2 /** Copyright © 2007-2010 Garmin Ltd. or its subsidiaries. 3 * 4 * Licensed under the Apache License, Version 2.0 (the 'License') 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an 'AS IS' BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * @fileoverview Garmin.MapController Overlays tracks and waypoint data on Google maps. 17 * @version 1.9 18 */ 19 /** 20 * Accepts Garmin.Series objects and draws them on a Google Map. 21 * 22 * @class Garmin.MapController 23 * @constructor 24 * @param (String) mapString id of element to place map in 25 */ 26 Garmin.MapController = function(mapString){}; //just here for jsdoc 27 Garmin.MapController = Class.create(); 28 Garmin.MapController.prototype = { 29 30 initialize: function(mapString) { 31 this.mapElement = $(mapString); 32 this.usePositionMarker = true; 33 34 this.polylines = new Array(); 35 this.markers = new Array(); 36 this.tracks = new Array(); 37 this.markerIndex = 0; 38 39 this.timeToCheck = false; 40 try { 41 this.map = new GMap2( $(mapString) ); 42 this.map.addControl(new GSmallMapControl()); 43 this.map.addControl(new GMapTypeControl()); 44 new GKeyboardHandler(this.map); 45 } catch (e) { 46 alert("WARNING: application will not function properly with missing Google script element or invalid Google map key. Error: "+e); 47 } 48 window.onUnload = "GUnload()"; 49 }, 50 51 /** Set the center point and zoom level of the map. 52 * @param (Number) Latitude of the center point 53 * @param (Number) Longitude of the center point 54 * @param (Number) Zoom level 55 */ 56 centerAndScale: function(lat, lon, scale) { 57 scale = (scale == null ? 13 : scale); 58 this.map.setCenter(new GLatLng(lat, lon), scale); 59 }, 60 61 /** Draw track on map. 62 * @param (Garmin.Track) The track to draw 63 * @param (String) Color in RGB Hex format, default: "#ff0000" 64 */ 65 drawTrack: function(series, color) { 66 color = (color == null ? "#ff0000" : color); 67 68 // create a smaller version of the whole track 69 // create 300 points or so ... 70 // Problem is that Google Maps dies when you hit near 500 points, so we have to 71 // ensure that we create fewer than that for the track. 72 var drawAt = Math.ceil(series.getSamplesLength()/300); 73 var drawnPoints = new Array(); 74 75 try { 76 // create up to 300 points 77 for(var h = 0; h < series.getSamplesLength(); h += drawAt) { 78 drawnPoints.push(this.createNearestValidLocationPoint(series, h, -1)); 79 } 80 // create the end point 81 drawnPoints.push(this.createNearestValidLocationPoint(series, series.getSamplesLength()-1, -1)); 82 } catch( e ) { 83 alert("GoogleMapControl.drawTrack: " + e.message); 84 } 85 86 if (drawnPoints.length > 0) { 87 //draw the new smaller version 88 var polyline = new GPolyline(drawnPoints, color, 2, .8) 89 try { 90 this.centerAndScale(drawnPoints[0].lat(), drawnPoints[0].lng()); 91 this.map.addOverlay( polyline ); 92 this.addStartFinishMarkers(series); 93 this.bounds = this.findAZoomLevel(drawnPoints); 94 this.setOnBounds( this.bounds ); 95 } catch(e){ alert("GoogleMapControl.drawTrack, IE error on map.addOverlay("+polyline+") err: "+e); } 96 } 97 }, 98 99 /**Creates a GLatLng for the sample in the series closest to the index with a valid location (lat and lon). 100 * @param series - The series to search through. 101 * @param index - The index to start searching from. 102 * @param incDirection - The direction to travel for the search. 103 * @return A GLatLng of the nearest valid location sample found. 104 */ 105 createNearestValidLocationPoint: function(series, index, incDirection) { 106 var sample = series.findNearestValidLocationSample(index, -1); 107 if (sample != null) { 108 var sampleLat = sample.getMeasurement(Garmin.Sample.MEASUREMENT_KEYS.latitude).getValue(); 109 var sampleLon = sample.getMeasurement(Garmin.Sample.MEASUREMENT_KEYS.longitude).getValue(); 110 return new GLatLng(sampleLat, sampleLon); 111 } else { 112 throw new Error("No valid location point in series."); 113 } 114 }, 115 116 /** Draw waypoint on map. 117 * @param (Garmin.Series) series containing a waypoint to add to the map 118 */ 119 drawWaypoint: function(series) { 120 var sample = series.getSample(0); 121 this.centerAndScale(sample.getLatitude(), sample.getLongitude(), 15); 122 this.addMarker(sample.getLatitude(), sample.getLongitude()); 123 }, 124 125 /** Calculates minimum bounding box for an set of points. 126 * @param (Array) The array of points to find a zoom level for 127 */ 128 findAZoomLevel: function(points) { 129 var bounds = new GLatLngBounds(points[0], points[0]); 130 131 for(var i=1; i<points.length-1; i+=3) { 132 bounds.extend(points[i]); 133 } 134 135 return bounds; 136 }, 137 138 /** Check the new dimensions of the map, and determine the bounds of the tracks 139 * Then set the map to zoom to that bound level 140 * @private 141 */ 142 sizeAndSetOnBounds: function() { 143 this.map.checkResize(); 144 this.setOnBounds( this.bounds ); 145 }, 146 147 /** Set the bounding box on the map. 148 * @param (GLatLngBounds) bounding box for the 149 */ 150 setOnBounds: function(bounds) { 151 this.map.setCenter( this.bounds.getCenter(), this.map.getBoundsZoomLevel(this.bounds) ); 152 }, 153 154 /** Add an icon to a point. 155 * @param {Number} latitude of marker 156 * @param {Number} longitude of marker 157 */ 158 addMarker: function(latitude, longitude) { 159 this.addMarkerWithIcon(latitude, longitude, Garmin.MapIcons.getRedIcon()); 160 }, 161 162 /** Adds a marker to the point with the icon specified 163 * @param {Number} latitude of marker 164 * @param {Number} longitude of marker 165 * @param (GIcon) icon to add at the point 166 */ 167 addMarkerWithIcon: function(latitude, longitude, icon) { 168 var gMarker = new GMarker(new GLatLng(latitude, longitude), icon); 169 this.markers.push(gMarker); 170 this.map.addOverlay(gMarker); 171 }, 172 173 /** Add start and finish markers to a track 174 * @param (Garmin.Series) The series to add markers to 175 */ 176 addStartFinishMarkers: function(series) { 177 var firstSample = series.getFirstValidLocationSample(); 178 var lastSample = series.getLastValidLocationSample(); 179 this.addMarkerWithIcon(firstSample.getLatitude(), firstSample.getLongitude(), Garmin.MapIcons.getGreenIcon()); 180 this.addMarkerWithIcon(lastSample.getLatitude(), lastSample.getLongitude(), Garmin.MapIcons.getRedIcon()); 181 }, 182 183 /** String representation of map. 184 * @return (String) 185 */ 186 toString: function() { 187 return "Google Based Map Controller, managing " + this.tracks.length + " track(s)"; 188 } 189 }; 190 191 /** Icons used to mark waypoints and POIs on Google maps. 192 * 193 * @class Garmin.MapIcons 194 * @constructor 195 */ 196 Garmin.MapIcons = function(){}; //just here for jsdoc 197 Garmin.MapIcons = { 198 getRedIcon: function() { 199 var icon = new GIcon(); 200 icon.image = "http://developer.garmin.com/img/marker_red.png"; 201 return Garmin.MapIcons._applyShadowAndStuff(icon); 202 }, 203 204 getGreenIcon: function() { 205 var icon = new GIcon(); 206 icon.image = "http://developer.garmin.com/img/marker_green.png"; 207 return Garmin.MapIcons._applyShadowAndStuff(icon); 208 }, 209 210 _applyShadowAndStuff: function(icon) { 211 icon.iconSize = new GSize(12, 20); 212 icon.shadow = "http://developer.garmin.com/img/marker_shadow.png"; 213 icon.shadowSize = new GSize(22, 20); 214 icon.iconAnchor = new GPoint(6, 20); 215 icon.infoWindowAnchor = new GPoint(5, 1); 216 return icon; 217 } 218 }