var interactive_map_styles = { standard : [], shiftworker : [{"stylers":[{"saturation":-100},{"gamma":1},{"lightness":"30"}]},{"featureType":"poi.business","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"poi.business","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"poi.place_of_worship","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"poi.place_of_worship","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"geometry","stylers":[{"visibility":"simplified"}]},{"featureType":"water","stylers":[{"visibility":"on"},{"saturation":50},{"gamma":0},{"color":"#B0D4E6"}]},{"featureType":"administrative.neighborhood","elementType":"labels.text.fill","stylers":[{"color":"#333333"}]},{"featureType":"all","elementType":"labels.text","stylers":[{"weight":0.2},{"color":"#555555"}]},{"featureType":"transit.station","elementType":"labels.icon","stylers":[{"gamma":1},{"saturation":50}]}] }; window.status = 0; function retractMarker(_index) { /* works only with single map environment */ var marker = myMarkers[''+_index.toUpperCase()+'']; marker.infowindow.close(); google.maps.event.trigger(marker, 'dblclick'); } function retractAllMarkers() { /* works only with single map environment */ for(var i in myMarkers) { google.maps.event.trigger(myMarkers[i], 'dblclick'); } } function drawCircle(map, center, radius, nodes, liColor, liWidth, liOpa, fillColor, fillOpa, radiusAngle) { // // add circle to map // var radiusM = radius * 1609.34; var radiusObject = {}; var circleOptions = { strokeColor: fillColor, strokeOpacity: 0.0, strokeWeight: liWidth, fillColor: fillColor, fillOpacity: 0.15, map: map, center: center, radius: radiusM }; poiCircle = new google.maps.Circle(circleOptions); // save reference radiusObject.rCircle = poiCircle; // // add radius line & mile marker // radiusObject.rLegend = drawRadiusLegend(map, center, radius, fillColor, radiusAngle); if(typeof dynamic_radius_point === 'undefined') { dynamic_radius_point = false; } if(dynamic_radius_point && nodes) { var marker = new google.maps.Marker({ position: center, map: map, icon: { // Star path: 'M 0,-24 6,-7 24,-7 10,4 15,21 0,11 -15,21 -10,4 -24,-7 -6,-7 z', fillColor: '#ffff00', fillOpacity: 1, scale: 1/4, strokeColor: '#bd8d2c', strokeWeight: 1 } }); } return radiusObject; } function drawMapArea(map, points_list, color, opacity, solid) { points_list = typeof(points_list) == 'undefined'? '' : points_list; color = typeof(color) == 'undefined'? 'blue' : color; opacity = typeof(opacity) == 'undefined'? '.1' : opacity; solid = typeof(solid) == 'undefined'? true : solid; var liWidth = 4; var list_array = points_list.split('|'); var points = []; for(var i=0; i 0 || _src.indexOf( 'php/poi' ) > 0) { iconW = 18; iconH = 18; } else if(_iconVenue.indexOf( 'bus' ) == 0) { // transit related if(_iconDirection == 'nb' || _iconDirection == 'sb') { iconW = 27; iconH = 23; } else if(_iconDirection == 'eb' || _iconDirection == 'wb') { iconW = 23; iconH = 27; } else { iconW = 27; iconH = 27; } } else { if(_iconDirection == 'nb' || _iconDirection == 'sb') { iconW = 35; iconH = 18; } else if(_iconDirection == 'eb' || _iconDirection == 'wb') { iconW = 18; iconH = 35; } else { iconW = 35; iconH = 35; } } // inventory style icon var invIcon = new google.maps.Icon(); invIcon.iconSize = new google.maps.Size(iconW * _scale, iconH * _scale); invIcon.iconAnchor = new google.maps.Point((iconW * _scale)/2, (iconH * _scale)/2); invIcon.infoWindowAnchor = new google.maps.Point((iconW * _scale)/2, (iconH * _scale)/2); return invIcon; } // internal function getIconSize(_src, _scale) { _src = _src.toLowerCase(); var _tmpArray = _src.split('/'); var _markerindex = 0; for(var i=0; i < _tmpArray.length; i++) { if(stristr(_tmpArray[i],'marker.php')) { _markerindex = i; } } var _iconVenue = _tmpArray[2+_markerindex]; var _iconDirection = _tmpArray[3+_markerindex]; var iconW; var iconH; // // quick calc for new icon style // if(_src.indexOf( 'mapicon' ) > 0 || _src.indexOf( 'mapIcon' ) > 0) { iconW = 30; iconH = 50; return [iconW, iconH, iconW*_scale, iconH*_scale]; } if(_src.indexOf( 'oaaa/advertiser' ) > 0 || _src.indexOf( 'php/poi' ) > 0) { iconW = 18; iconH = 18; } else if(_iconVenue.indexOf( 'bus' ) == 0) { // transit related if(_iconDirection == 'nb' || _iconDirection == 'sb') { iconW = 27; iconH = 23; } else if(_iconDirection == 'eb' || _iconDirection == 'wb') { iconW = 23; iconH = 27; } else { iconW = 27; iconH = 27; } } else { if(_iconDirection == 'nb' || _iconDirection == 'sb') { iconW = 35; iconH = 18; } else if(_iconDirection == 'eb' || _iconDirection == 'wb') { iconW = 17; iconH = 34; } else { iconW = 35; iconH = 35; } } //alert(_iconVenue+":"+_iconDirection+":"+iconW+":"+ iconH+":"+ iconW*_scale/1.2+":"+ iconH*_scale/1.2); return [iconW, iconH, iconW*_scale, iconH*_scale]; } // called externally function checkBrowser(elementId, mouse_scroll) { var map = {}; if (!stristr(elementId, 'none')) { window.status++; } mouse_scroll = typeof mouse_scroll !== 'undefined' ? mouse_scroll : false; try { map = new google.maps.Map( document.getElementById(elementId), { scrollwheel: mouse_scroll, styles: interactive_map_style, scaleControl: true, mapTypeId: google.maps.MapTypeId.ROADMAP }); // shift key if(map.enableKeyDragZoom) { map.enableKeyDragZoom(); } function call_redraw() { if(typeof(redraw) === 'undefined') { console.log('no redraw'); } else { redraw(); } }; google.maps.event.addListenerOnce(map, 'tilesloaded', function() { setTimeout(function() { window.status--; console.log(window.status); call_redraw(); }, 2500); }); map.myMarkers = []; map.bounds = new google.maps.LatLngBounds(); map.setOptions({streetViewControl: false}); centerNZoom(map); } catch (err) { // document.write is helpful for PDF generator debugging // document.write(err); // remove status increment because there was a failure above if (!stristr(elementId, 'none')) { window.status--; } } return map; } // called externally function centerNZoom(map, _adjust) { map.setCenter(map.bounds.getCenter()); map.fitBounds(map.bounds); } function makeSmallMap(divName, _src, _text, _zoom) { var bounds = new google.maps.LatLng(); var map = new google.maps.Map( document.getElementById(divName), { styles: interactive_map_style, }); _src = _src.toLowerCase(); var tmpArray = _src.split('/'); var lat = tmpArray[7]; var lng = tmpArray[8]; var iconColor = tmpArray[2]; if (tmpArray[5] != 'null') { iconColor = tmpArray[5]; } var _countOverride = '0'; var imgname = "/res/mapIcon/"+tmpArray[3].toLowerCase()+"/null/"+_countOverride+"/null/"+iconColor+"/dot.png"; var invIconSize = getIconSize(imgname, 1); //var imgname = "/apx/proposalForm/imgs/csh_bluebooks/marker.php/"+tmpArray[1]+"/"+tmpArray[2]+"/"+tmpArray[3]+"/1/"+tmpArray[5]+"/"+_text+"/"+lat+"/"+lng+"/null"; //var invIconSize = getIconSize(imgname, 1); var shape = { coord: [1, 1, 1, invIconSize[1], invIconSize[0], invIconSize[1], invIconSize[0] , 1], type: 'poly' }; var image = { url: imgname, // This marker is 20 pixels wide by 32 pixels tall. size: new google.maps.Size(invIconSize[0], invIconSize[1]), // The origin for this image is 0,0. origin: new google.maps.Point(0,0), // The anchor for this image is the base of the flagpole at 0,32. //anchor: new google.maps.Point(invIconSize[2], 0) anchor: new google.maps.Point(invIconSize[0]/2, invIconSize[1]) }; // determine location & create marker var point = new google.maps.LatLng(lat,lng); //var marker = new OffsetableMarker(point, {icon:bicon3,zIndexProcess:importanceOrder}); var marker = new google.maps.Marker({ position: point, map: map, icon: image }); map.setCenter(new google.maps.LatLng(lat,lng)); map.setMapTypeId(google.maps.MapTypeId.ROADMAP); map.setOptions({streetViewControl: false}); map.setZoom(_zoom); } // called externally marker_zyyy1 = 1; // must be global globalInfoWindow = null;// must be global function createTabbedMarker(map, _text,_src,labels,htmls_input,_scale, title, zindex, onlyOneInfoWindow, width, height) { //alert(map.myName); // // test code (!map) . . . // //if(!map) { // make a map. why not! //map = checkBrowser(mapName); //} if(typeof(htmls_input) == 'string') { htmls = htmls_input; } else { var htmls = htmls_input.join(''); } var interactive_view = false; if(stristr(htmls,'interactive_view:')) { interactive_view = true; htmls = htmls.replace('interactive_view:', ''); } if(!title) { title=''; } marker_zyyy1++; var htmlsx = [ '
', '', '
', '

Tab 1:'+marker_zyyy1+'

', '
', '
', '

Tab 2:'+marker_zyyy1+'

', '
', '
', '

Tab 3:'+marker_zyyy1+'

', '
', '
' ].join(''); _src = _src.toLowerCase(); var tmpArray = _src.split('/'); var lat = tmpArray[7]; var lng = tmpArray[8]; if(lat == 0 || lng == 0) { return null; } var radius_flag = tmpArray[2] == 'radius'? true: false; if(radius_flag) { //_scale = 1.2; _scale = typeof _scale !== 'undefined' ? _scale : '1.2'; } ///res/mapIcon/wb/21/3/null/blue/dot.png // //1 = oaaa //2 = venue //3 = direction //5 = color // if (tmpArray[5] == 'null') { tmpArray[5] = tmpArray[2]; } else if (tmpArray[5].indexOf(':')) { var colorsArray = tmpArray[5].split(':'); var venuesArray = tmpArray[2].split(':'); for (var i = colorsArray.length - 1; i >= 0; i--) { if (colorsArray[i] == 'null') { colorsArray[i] = venuesArray[i]; } } tmpArray[5] = colorsArray.join(':'); } /* if(tmpArray[2].toLowerCase() =='bulletin') { tmpArray[5] = 'blue'; } else if(stristr(tmpArray[2],'tri')) { tmpArray[5] = 'purple'; } else if(stristr(tmpArray[2],'8')) { tmpArray[5] = 'green'; } else if(stristr(tmpArray[2],'30')) { tmpArray[5] = 'red'; } else if(stristr(tmpArray[2],'city')) { tmpArray[5] = 'red'; } else if(stristr(tmpArray[2],'junior')) { tmpArray[5] = 'red'; } else if(stristr(tmpArray[2],'digital')) { tmpArray[5] = 'black'; } else if(stristr(tmpArray[2],'bench')) { tmpArray[5] = 'green'; } else if(stristr(tmpArray[2],'shelter')) { tmpArray[5] = 'purple'; } else if(stristr(tmpArray[2],'kiosk')) { tmpArray[5] = 'purple'; } else if(stristr(tmpArray[2],'exter')) { tmpArray[5] = 'purple'; } } */ if(stristr(tmpArray[3], ':')) { var _countOverride = 'null'; } else { var _countOverride = '0'; } //var invIconSize = getIconSize(_src, _scale); //var imgname = "/apx/proposalForm/imgs/csh_bluebooks/marker.php/"+tmpArray[1]+"/"+tmpArray[2]+"/"+tmpArray[3]+"/"+_scale+"/"+tmpArray[5]+"/"+_text+"/"+lat+"/"+lng+"/null"; //var imgname = "/res/mapIcon/"+tmpArray[3].toLowerCase()+"/"+_text+"/"+_countOverride+"/null/"+tmpArray[5]+"/dot.png"; var imgname = "/res/mapIcon/"+tmpArray[3].toLowerCase()+"/"+_text+"/"+_countOverride+"/null/"+tmpArray[5]+"/dot.png"; var invIconSize = getIconSize(imgname, _scale); var shape = { coord: [1, 1, 1, invIconSize[1], invIconSize[0], invIconSize[1], invIconSize[0] , 1], type: 'poly' }; /* var image = { url: imgname, // This marker is 20 pixels wide by 32 pixels tall. size: new google.maps.Size(invIconSize[0], invIconSize[1]), // The origin for this image is 0,0. origin: new google.maps.Point(0,0), // The anchor for this image is the base of the flagpole at 0,32. anchor: new google.maps.Point(invIconSize[2], invIconSize[3]) }; */ if(_scale == 1) { var image = new google.maps.MarkerImage( imgname, null, null, null, null ); } else { var image = new google.maps.MarkerImage( imgname, null, null, null, new google.maps.Size(invIconSize[2], invIconSize[3]) ); } // determine location & create marker var point = new google.maps.LatLng(lat,lng); //var marker = new OffsetableMarker(point, {icon:bicon3,zIndexProcess:importanceOrder}); if(!zindex) { var marker = new google.maps.Marker({ position: point, map: map, icon: image, shape: shape, draggable: true, original_position: point, polyline: null, title: title }); } else { var marker = new google.maps.Marker({ position: point, map: map, icon: image, shape: shape, title: title, draggable: true, original_position: point, polyline: null, zIndex: zindex }); } // // record marker here // map.bounds.extend(point); if(radius_flag) { } else { // // if there is label text . . . // if(labels == '') { } else { var tmp_label_array = labels.split(':'); var tmp_label_text = tmp_label_array[0]; if(tmp_label_array.length > 1) { var tmp_label_position = tmp_label_array[1]; } else { var tmp_label_position = ''; } var myL = drawMarkerLabel(map, point, tmp_label_text, tmp_label_position); } //var myL = drawMarkerLabel(map, point, 'one', ''); } var poly = new google.maps.Polyline({ map: map, strokeColor: '#000000', strokeOpacity: 1.0, strokeWeight: 1 }); // // make poly accessible from marker reference // //marker.myPoly = poly; //marker.myRef = map.myName+_text; marker.myName = _text; marker.myShift = ''; marker.myPoint = point; google.maps.event.addListener(marker, 'position_changed', function() { poly.setPath([]); poly.getPath().push(point); poly.getPath().push(marker.getPosition()); marker.myShift = marker.getPosition(); // // move label with marker // if(typeof(myL) !== 'undefined') { myL.set('position', marker.getPosition()); } }); if(interactive_view) { google.maps.event.addListener(marker, 'click', function() { //var tmp = htmls.split('|'); //show_mini_photosheet(tmp[0],tmp[1]); show_mini_photosheet(htmls); }); } else { google.maps.event.addListener(marker, 'click', function() { marker.setPosition(point); if(marker.infowindow) { marker.infowindow.close(); } marker.myShift = ''; //marker.setPosition(new google.maps.LatLng(41.19250000,-104.83770000)); }); } google.maps.event.addListener(marker, 'dblclick', function() { marker.setPosition(point); if(marker.infowindow) { marker.infowindow.close(); } marker.myShift = ''; }); /* if(1==2 && htmls != '') { var infowindow = new google.maps.InfoWindow({ content: htmls }); infowindow.tabid = marker_zyyy1; google.maps.event.addListener(infowindow, 'domready', function() { $("#tab"+infowindow.tabid).tabs(); }); marker.infowindow = infowindow; marker.tabid = marker_zyyy1; google.maps.event.addListener(marker, 'click', function() { marker.infowindow.open(map,marker); globalInfoWindow = marker.infowindow; }); } */ // keep track of markers map.myMarkers[''+_text+''] = marker; return marker; } function createRadiusMileMarker(map, _text,_src,labels,htmls_input,_scale, title, zindex, onlyOneInfoWindow, width, height) { if(!title) { title=''; } marker_zyyy1++; _src = _src.toLowerCase(); var tmpArray = _src.split('/'); var lat = tmpArray[7]; var lng = tmpArray[8]; var radius_flag = tmpArray[2] == 'radius'? true: false; if(radius_flag) { _scale = typeof _scale !== 'undefined' ? _scale : '1.2'; //_scale = 1.2; } var invIconSize = getIconSize(_src, _scale); var imgname = "/apx/proposalForm/imgs/csh_bluebooks/marker.php/"+tmpArray[1]+"/"+tmpArray[2]+"/"+tmpArray[3]+"/"+_scale+"/"+tmpArray[5]+"/"+_text+"/"+lat+"/"+lng+"/null"; var shape = { coord: [1, 1, 1, invIconSize[1], invIconSize[0], invIconSize[1], invIconSize[0] , 1], type: 'poly' }; if(_scale == 1) { var image = new google.maps.MarkerImage( imgname, null, null, null, null ); } else { var image = new google.maps.MarkerImage( imgname, null, null, null, new google.maps.Size(invIconSize[2], invIconSize[3]) ); } // determine location & create marker var point = new google.maps.LatLng(lat,lng); //var marker = new OffsetableMarker(point, {icon:bicon3,zIndexProcess:importanceOrder}); if(!zindex) { var marker = new google.maps.Marker({ position: point, map: map, icon: image, shape: shape, draggable: false, original_position: point, polyline: null, title: title }); } else { var marker = new google.maps.Marker({ position: point, map: map, icon: image, shape: shape, title: title, draggable: false, original_position: point, polyline: null, zIndex: zindex }); } // // record marker here // map.bounds.extend(point); var poly = new google.maps.Polyline({ map: map, strokeColor: '#000000', strokeOpacity: 1.0, strokeWeight: 1 }); google.maps.event.addListener(marker, 'position_changed', function() { poly.setPath([]); poly.getPath().push(point); poly.getPath().push(marker.getPosition()); // // move label with marker // if(typeof(myL) !== 'undefined') { myL.set('position', marker.getPosition()); } }); google.maps.event.addListener(marker, 'click', function() { marker.setPosition(point); if(marker.infowindow) { marker.infowindow.close(); } }); google.maps.event.addListener(marker, 'dblclick', function() { marker.setPosition(point); if(marker.infowindow) { marker.infowindow.close(); } }); // do NOT keep track of radius label markers //map.myMarkers[''+_text+''] = marker; return marker; } function makeMultiMap(divName, _src, _text, _zoom) { var map = checkBrowser(divName); var listArray = _src.split('|'); for (var i=0; i < listArray.length; i = i+1) { createTabbedMarker(map, i+1,listArray[i],'','',1, '', '' ); } if(listArray.length == 1) { var tmp = listArray[0].split('/'); var lat = tmp[7]; var lng = tmp[8]; var point = new google.maps.LatLng(lat,lng); addInvisiblePoint(map, point, .8, 90); addInvisiblePoint(map, point, .8, 180); addInvisiblePoint(map, point, .8, 270); addInvisiblePoint(map, point, .8, 360); } } // called externally function createMarker(map, _src, _text,labels,htmls_input,_scale, title, zindex, onlyOneInfoWindow, width, height) { //Tabbed // // defaults parm values // _text = typeof _text !== 'undefined' ? _text : ''; labels = typeof labels !== 'undefined' ? labels : ''; htmls_input = typeof htmls_input !== 'undefined' ? htmls_input : ''; _scale = typeof _scale !== 'undefined' ? _scale : '1'; title = typeof title !== 'undefined' ? title : ''; zindex = typeof zindex !== 'undefined' ? zindex : ''; onlyOneInfoWindow = typeof onlyOneInfoWindow !== 'undefined' ? onlyOneInfoWindow : ''; width = typeof width !== 'undefined' ? width : ''; height = typeof height !== 'undefined' ? height : ''; // // // if(typeof(htmls_input) == 'string') { htmls = htmls_input; } else { var htmls = htmls_input.join(''); } if(!title) { title=''; } marker_zyyy1++; var htmlsx = [ '
', '', '
', '

Tab 1:'+marker_zyyy1+'

', '
', '
', '

Tab 2:'+marker_zyyy1+'

', '
', '
', '

Tab 3:'+marker_zyyy1+'

', '
', '
' ].join(''); _src = _src.toLowerCase(); var tmpArray = _src.split('/'); var lat = tmpArray[7]; var lng = tmpArray[8]; //if(tmpArray[5] == 'null') { if(tmpArray[5] == 'null') { tmpArray[5] = tmpArray[2]; } /* if(1==2 && tmpArray[5] == 'null') { if(tmpArray[2].toLowerCase() =='bulletin') { tmpArray[5] = 'blue'; } else if(stristr(tmpArray[2],'tri')) { tmpArray[5] = 'purple'; } else if(stristr(tmpArray[2],'8')) { tmpArray[5] = 'green'; } else if(stristr(tmpArray[2],'30')) { tmpArray[5] = 'red'; } else if(stristr(tmpArray[2],'city')) { tmpArray[5] = 'red'; } else if(stristr(tmpArray[2],'junior')) { tmpArray[5] = 'red'; } else if(stristr(tmpArray[2],'digital')) { tmpArray[5] = 'black'; } else if(stristr(tmpArray[2],'bench')) { tmpArray[5] = 'green'; } else if(stristr(tmpArray[2],'shelter')) { tmpArray[5] = 'purple'; } else if(stristr(tmpArray[2],'kiosk')) { tmpArray[5] = 'purple'; } else if(stristr(tmpArray[2],'exter')) { tmpArray[5] = 'purple'; } } */ // // // // string.match looking for pattern: oaaa/foobar.ext/ or oaaa/advertiser to prevent overrides of special icons if(stristr(_src,'oaaa') && !_src.match(/oaaa\/.*\....\/|advertiser/)) { var imgname = "/res/mapIcon/"+tmpArray[3].toLowerCase()+"/null/0/null/"+tmpArray[5]+"/dot.png"; var invIconSize = getIconSize(imgname, _scale); var anchor_point = new google.maps.Point(invIconSize[0]/2*_scale, invIconSize[1]*_scale); } else { var imgname = "imgs/csh_bluebooks/"+_src.replace(lat, 'null').replace(lng, 'null'); var invIconSize = getIconSize(imgname, _scale); var anchor_point = new google.maps.Point(invIconSize[0]/2*_scale, invIconSize[1]/2*_scale); } var shape = { coord: [1, 1, 1, invIconSize[1], invIconSize[0], invIconSize[1], invIconSize[0] , 1], type: 'poly' }; /* var image = { url: imgname, // This marker is 20 pixels wide by 32 pixels tall. size: new google.maps.Size(invIconSize[0], invIconSize[1]), // The origin for this image is 0,0. origin: new google.maps.Point(0,0), // The anchor for this image is the base of the flagpole at 0,32. anchor: new google.maps.Point(10, 10) //anchor: new google.maps.Point(invIconSize[2]/2, invIconSize[3]/2) }; */ if(_scale == 1) { var image = new google.maps.MarkerImage( imgname, null, null, anchor_point, null ); } else { var image = new google.maps.MarkerImage( imgname, null, null, null, new google.maps.Size(invIconSize[2], invIconSize[3]) ); } //new google.maps.Size(invIconSize[2], invIconSize[3]) // determine location & create marker var point = new google.maps.LatLng(lat,lng); //var marker = new OffsetableMarker(point, {icon:bicon3,zIndexProcess:importanceOrder}); if(!zindex) { //var marker = new tMarker({ var marker = new google.maps.Marker({ position: point, map: map, icon: image, shape: shape, title: title }); } else { //var marker = new tMarker({ var marker = new google.maps.Marker({ position: point, map: map, icon: image, shape: shape, title: title, zIndex: zindex }); } //google.maps.event.addListener(marker, 'position_changed', function() { alert('c'); }); // // // // var poly = new google.maps.Polyline({ // map: map, // strokeColor: '#FF0000', // strokeOpacity: 1.0, // strokeWeight: 3 // }); //poly.setMap(marker_properties.map); /*google.maps.event.addListener(marker, 'position_changed', function() { alert('a'); poly.setPath([]); poly.getPath().push(point); poly.getPath().push(marker.getPosition()); }); */ map.bounds.extend(point); /* if(labels != '' && htmls != '') { GEvent.addListener(marker, "click", function() { if (htmls.length > 2) { htmls[0] = '
' + htmls[0] + '
'; } var tabs = []; for (var i=0; i(shift | ctrl | alt) * while dragging a box around an area of interest will zoom the map * to that area when the hot key is released. * Only one line of code is needed: google.maps.Map.enableKeyDragZoom(); *

* Note that if the map's container has a border around it, the border widths must be specified * in pixel units (or as thin, medium, or thick). This is required because of an MSIE limitation. *

NL: 2009-05-28: initial port to core API V3. */ /*! * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function () { /*jslint browser:true */ /*global google */ /** * Converts 'thin', 'medium', and 'thick' to pixel widths * in an MSIE environment. Not called for other browsers * because getComputedStyle() returns pixel widths automatically. * @param {String} widthValue */ var toPixels = function (widthValue) { var px; switch (widthValue) { case 'thin': px = "2px"; break; case 'medium': px = "4px"; break; case 'thick': px = "6px"; break; default: px = widthValue; } return px; }; /** * Get the widths of the borders of an HTML element. * * @param {Object} h HTML element * @return {Object} widths object (top, bottom left, right) */ var getBorderWidths = function (h) { var computedStyle; var bw = {}; if (document.defaultView && document.defaultView.getComputedStyle) { computedStyle = h.ownerDocument.defaultView.getComputedStyle(h, ""); if (computedStyle) { // The computed styles are always in pixel units (good!) bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0; bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0; bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0; return bw; } } else if (document.documentElement.currentStyle) { // MSIE if (h.currentStyle) { // The current styles may not be in pixel units so try to convert (bad!) bw.top = parseInt(toPixels(h.currentStyle.borderTopWidth), 10) || 0; bw.bottom = parseInt(toPixels(h.currentStyle.borderBottomWidth), 10) || 0; bw.left = parseInt(toPixels(h.currentStyle.borderLeftWidth), 10) || 0; bw.right = parseInt(toPixels(h.currentStyle.borderRightWidth), 10) || 0; return bw; } } // Shouldn't get this far for any modern browser bw.top = parseInt(h.style["border-top-width"], 10) || 0; bw.bottom = parseInt(h.style["border-bottom-width"], 10) || 0; bw.left = parseInt(h.style["border-left-width"], 10) || 0; bw.right = parseInt(h.style["border-right-width"], 10) || 0; return bw; }; /** * Get the position of the mouse relative to the document. * @param {Object} e Mouse event * @return {Object} left & top position */ var getMousePosition = function (e) { var posX = 0, posY = 0; e = e || window.event; if (typeof e.pageX !== "undefined") { posX = e.pageX; posY = e.pageY; } else if (typeof e.clientX !== "undefined") { posX = e.clientX + (typeof document.documentElement.scrollLeft !== "undefined" ? document.documentElement.scrollLeft : document.body.scrollLeft); posY = e.clientY + (typeof document.documentElement.scrollTop !== "undefined" ? document.documentElement.scrollTop : document.body.scrollTop); } return { left: posX, top: posY }; }; /** * Get the position of an HTML element relative to the document. * @param {Object} h HTML element * @return {Object} left & top position */ var getElementPosition = function (h) { var posX = h.offsetLeft; var posY = h.offsetTop; var parent = h.offsetParent; // Add offsets for all ancestors in the hierarchy while (parent !== null) { // Adjust for scrolling elements which may affect the map position. // // See http://www.howtocreate.co.uk/tutorials/javascript/browserspecific // // "...make sure that every element [on a Web page] with an overflow // of anything other than visible also has a position style set to // something other than the default static..." if (parent !== document.body && parent !== document.documentElement) { posX -= parent.scrollLeft; posY -= parent.scrollTop; } posX += parent.offsetLeft; posY += parent.offsetTop; parent = parent.offsetParent; } return { left: posX, top: posY }; }; /** * Set the properties of an object to those from another object. * @param {Object} obj target object * @param {Object} vals source object */ var setVals = function (obj, vals) { if (obj && vals) { for (var x in vals) { if (vals.hasOwnProperty(x)) { obj[x] = vals[x]; } } } return obj; }; /** * Set the opacity. If op is not passed in, this function just performs an MSIE fix. * @param {Node} div * @param {Number} op (0-1) */ var setOpacity = function (div, op) { if (typeof op !== 'undefined') { div.style.opacity = op; } if (typeof div.style.opacity !== 'undefined') { div.style.filter = "alpha(opacity=" + (div.style.opacity * 100) + ")"; } }; /** * @name KeyDragZoomOptions * @class This class represents the optional parameter passed into google.maps.Map.enableDragBoxZoom. * @property {String} [key] the hot key to hold down to activate a drag zoom, shift | ctrl | alt. * The default is shift. * @property {Object} [boxStyle] the css style of the zoom box. * The default is {border: 'thin solid #FF0000'}. * Border widths must be specified in pixel units (or as thin, medium, or thick). * @property {Object} [paneStyle] the css style of the pane which overlays the map when a drag zoom is activated. * The default is {backgroundColor: 'white', opacity: 0.0, cursor: 'crosshair'}. */ /** * @name DragZoom * @class This class represents a drag zoom object for a map. The object is activated by holding down the hot key. * This object is created when google.maps.Map.enableKeyDragZoom is called; it cannot be created directly. * Use google.maps.Map.getDragZoomObject to gain access to this object in order to attach event listeners. * @param {google.maps.Map} map * @param {KeyDragZoomOptions} opt_zoomOpts */ function DragZoom(map, opt_zoomOpts) { var ov = new google.maps.OverlayView(); var me = this; ov.onAdd = function () { me.init_(map, opt_zoomOpts); }; ov.draw = function () { }; ov.onRemove = function () { }; ov.setMap(map); this.prjov_ = ov; } /** * Init the tool. * @param {google.maps.Map} map * @param {KeyDragZoomOptions} opt_zoomOpts */ DragZoom.prototype.init_ = function (map, opt_zoomOpts) { this.map_ = map; opt_zoomOpts = opt_zoomOpts || {}; this.key_ = opt_zoomOpts.key || 'shift'; this.key_ = this.key_.toLowerCase(); this.borderWidths_ = getBorderWidths(this.map_.getDiv());//Container()); this.paneDiv_ = document.createElement("div"); this.paneDiv_.onselectstart = function () { return false; }; // default style setVals(this.paneDiv_.style, { backgroundColor: 'white', opacity: 0.0, cursor: 'crosshair' }); // allow overwrite setVals(this.paneDiv_.style, opt_zoomOpts.paneStyle); // stuff that cannot be overwritten setVals(this.paneDiv_.style, { position: 'absolute', overflow: 'hidden', zIndex: 10001, display: 'none' }); if (this.key_ === 'shift') { // Workaround for Firefox Shift-Click problem this.paneDiv_.style.MozUserSelect = "none"; } setOpacity(this.paneDiv_); // An IE fix: if the background is transparent, it cannot capture mousedown events if (this.paneDiv_.style.backgroundColor === 'transparent') { this.paneDiv_.style.backgroundColor = 'white'; setOpacity(this.paneDiv_, 0); } this.map_.getDiv().appendChild(this.paneDiv_);//Container() this.boxDiv_ = document.createElement('div'); setVals(this.boxDiv_.style, { border: 'thin solid #FF0000' }); setVals(this.boxDiv_.style, opt_zoomOpts.boxStyle); setVals(this.boxDiv_.style, { position: 'absolute', display: 'none' }); setOpacity(this.boxDiv_); this.map_.getDiv().appendChild(this.boxDiv_); this.boxBorderWidths_ = getBorderWidths(this.boxDiv_); var me = this; this.keyDownListener_ = google.maps.event.addDomListener(document, 'keydown', function (e) { me.onKeyDown_(e); }); this.keyUpListener_ = google.maps.event.addDomListener(document, 'keyup', function (e) { me.onKeyUp_(e); }); this.mouseDownListener_ = google.maps.event.addDomListener(this.paneDiv_, 'mousedown', function (e) { me.onMouseDown_(e); }); this.mouseDownListenerDocument_ = google.maps.event.addDomListener(document, 'mousedown', function (e) { me.onMouseDownDocument_(e); }); this.mouseMoveListener_ = google.maps.event.addDomListener(document, 'mousemove', function (e) { me.onMouseMove_(e); }); this.mouseUpListener_ = google.maps.event.addDomListener(document, 'mouseup', function (e) { me.onMouseUp_(e); }); this.hotKeyDown_ = false; this.dragging_ = false; this.startPt_ = null; this.endPt_ = null; this.boxMaxX_ = null; this.boxMaxY_ = null; this.mousePosn_ = null; this.mapPosn_ = getElementPosition(this.map_.getDiv()); this.mouseDown_ = false; }; /** * Returns true if the hot key is being pressed when an event occurs. * @param {Event} e * @return {Boolean} */ DragZoom.prototype.isHotKeyDown_ = function (e) { var isHot; e = e || window.event; isHot = (e.shiftKey && this.key_ === 'shift') || (e.altKey && this.key_ === 'alt') || (e.ctrlKey && this.key_ === 'ctrl'); if (!isHot) { // Need to look at keyCode for Opera because it // doesn't set the shiftKey, altKey, ctrlKey properties // unless a non-modifier event is being reported. // // See http://cross-browser.com/x/examples/shift_mode.php // Also see http://unixpapa.com/js/key.html switch (e.keyCode) { case 16: if (this.key_ === 'shift') { isHot = true; } break; case 17: if (this.key_ === 'ctrl') { isHot = true; } break; case 18: if (this.key_ === 'alt') { isHot = true; } break; } } return isHot; }; /** * Checks if the mouse is on top of the map. The position is captured * in onMouseMove_. * @return true if mouse is on top of the map div. */ DragZoom.prototype.isMouseOnMap_ = function () { var mousePos = this.mousePosn_; if (mousePos) { var mapPos = this.mapPosn_; var mapDiv = this.map_.getDiv(); return mousePos.left > mapPos.left && mousePos.left < mapPos.left + mapDiv.offsetWidth && mousePos.top > mapPos.top && mousePos.top < mapPos.top + mapDiv.offsetHeight; } else { // if user never moved mouse return false; } }; /** * Show or hide the overlay pane, depending on whether the mouse is over the map. */ DragZoom.prototype.setPaneVisibility_ = function () { if (this.map_ && this.hotKeyDown_ && this.isMouseOnMap_()) { var mapDiv = this.map_.getDiv(); this.paneDiv_.style.left = 0 + 'px'; this.paneDiv_.style.top = 0 + 'px'; this.paneDiv_.style.width = mapDiv.offsetWidth - (this.borderWidths_.left + this.borderWidths_.right) + 'px'; this.paneDiv_.style.height = mapDiv.offsetHeight - (this.borderWidths_.top + this.borderWidths_.bottom) + 'px'; this.paneDiv_.style.display = 'block'; this.boxMaxX_ = parseInt(this.paneDiv_.style.width, 10) - (this.boxBorderWidths_.left + this.boxBorderWidths_.right); this.boxMaxY_ = parseInt(this.paneDiv_.style.height, 10) - (this.boxBorderWidths_.top + this.boxBorderWidths_.bottom); } else { this.paneDiv_.style.display = 'none'; } }; /** * Handle key down. Activate the tool only if the mouse is on top of the map. * @param {Event} e */ DragZoom.prototype.onKeyDown_ = function (e) { var me = this; if (this.map_ && !this.hotKeyDown_ && this.isHotKeyDown_(e)) { me.hotKeyDown_ = true; me.setPaneVisibility_(); /** * This event is fired when the hot key is pressed. * @name DragZoom#activate * @event */ google.maps.event.trigger(me, 'activate'); } }; /** * Get the google.maps.Point of the mouse position. * @param {Object} e * @return {google.maps.Point} point * @private */ DragZoom.prototype.getMousePoint_ = function (e) { var mousePosn = getMousePosition(e); var p = new google.maps.Point(); p.x = mousePosn.left - this.mapPosn_.left - this.borderWidths_.left; p.y = mousePosn.top - this.mapPosn_.top - this.borderWidths_.top; p.x = Math.min(p.x, this.boxMaxX_); p.y = Math.min(p.y, this.boxMaxY_); p.x = Math.max(p.x, 0); p.y = Math.max(p.y, 0); return p; }; /** * Handle mouse down. * @param {Event} e */ DragZoom.prototype.onMouseDown_ = function (e) { if (this.map_ && this.hotKeyDown_) { this.mapPosn_ = getElementPosition(this.map_.getDiv()); this.dragging_ = true; this.startPt_ = this.endPt_ = this.getMousePoint_(e); var prj = this.prjov_.getProjection(); var latlng = prj.fromDivPixelToLatLng(this.startPt_); /** * This event is fired when the drag operation begins. * @name DragZoom#dragstart * @param {GLatLng} startLatLng * @event */ google.maps.event.trigger(this, 'dragstart', latlng); } }; /** * Handle mouse down at the document level. * @param {Event} e */ DragZoom.prototype.onMouseDownDocument_ = function (e) { this.mouseDown_ = true; }; /** * Handle mouse move. * @param {Event} e */ DragZoom.prototype.onMouseMove_ = function (e) { this.mousePosn_ = getMousePosition(e); if (this.dragging_) { this.endPt_ = this.getMousePoint_(e); var left = Math.min(this.startPt_.x, this.endPt_.x); var top = Math.min(this.startPt_.y, this.endPt_.y); var width = Math.abs(this.startPt_.x - this.endPt_.x); var height = Math.abs(this.startPt_.y - this.endPt_.y); this.boxDiv_.style.left = left + 'px'; this.boxDiv_.style.top = top + 'px'; this.boxDiv_.style.width = width + 'px'; this.boxDiv_.style.height = height + 'px'; this.boxDiv_.style.display = 'block'; /** * This event is repeatedly fired while the user drags the box. The southwest and northeast * point are passed as parameters of type google.maps.Point (for performance reasons), * relative to the map container. Note: the event listener is responsible * for converting Pixel to LatLng, if necessary. * @name DragZoom#drag * @param {google.maps.Point} southwestPixel * @param {google.maps.Point} northeastPixel * @event */ google.maps.event.trigger(this, 'drag', new google.maps.Point(left, top + height), new google.maps.Point(left + width, top)); } else if (!this.mouseDown_) { this.setPaneVisibility_(); } }; /** * Handle mouse up. * @param {Event} e */ DragZoom.prototype.onMouseUp_ = function (e) { this.mouseDown_ = false; if (this.dragging_) { var left = Math.min(this.startPt_.x, this.endPt_.x); var top = Math.min(this.startPt_.y, this.endPt_.y); var width = Math.abs(this.startPt_.x - this.endPt_.x); var height = Math.abs(this.startPt_.y - this.endPt_.y); var prj = this.prjov_.getProjection(); // 2009-05-29: since V3 does not have fromContainerPixel, //needs find offset here var containerPos = getElementPosition(this.map_.getDiv()); var mapPanePos = getElementPosition(this.prjov_.getPanes().mapPane); left = left + (containerPos.left - mapPanePos.left); top = top + (containerPos.top - mapPanePos.top); var sw = prj.fromDivPixelToLatLng(new google.maps.Point(left, top + height)); var ne = prj.fromDivPixelToLatLng(new google.maps.Point(left + width, top)); var bnds = new google.maps.LatLngBounds(sw, ne); this.map_.fitBounds(bnds); this.dragging_ = false; this.boxDiv_.style.display = 'none'; /** * This event is fired when the drag operation ends. * Note that the event is not fired if the hot key is released before the drag operation ends. * @name DragZoom#dragend * @param {GLatLngBounds} newBounds * @event */ google.maps.event.trigger(this, 'dragend', bnds); } }; /** * Handle key up. * @param {Event} e */ DragZoom.prototype.onKeyUp_ = function (e) { if (this.map_ && this.hotKeyDown_) { this.hotKeyDown_ = false; this.dragging_ = false; this.boxDiv_.style.display = 'none'; this.paneDiv_.style.display = "none"; /** * This event is fired while the user release the key * @name DragZoom#deactivate * @event */ google.maps.event.trigger(this, 'deactivate'); } }; /** * @name google.maps.Map * @class These are new methods added to the Google Maps API's * Map * class. */ /** * Enable drag zoom. The user can zoom to an area of interest by holding down the hot key * (shift | ctrl | alt ) while dragging a box around the area. * @param {KeyDragZoomOptions} opt_zoomOpts */ google.maps.Map.prototype.enableKeyDragZoom = function (opt_zoomOpts) { this.dragZoom_ = new DragZoom(this, opt_zoomOpts); }; /** * Disable drag zoom. */ google.maps.Map.prototype.disableKeyDragZoom = function () { var d = this.dragZoom_; if (d) { google.maps.event.removeListener(d.mouseDownListener_); google.maps.event.removeListener(d.mouseDownListenerDocument_); google.maps.event.removeListener(d.mouseMoveListener_); google.maps.event.removeListener(d.mouseUpListener_); google.maps.event.removeListener(d.keyUpListener_); google.maps.event.removeListener(d.keyDownListener_); this.getDiv().removeChild(d.boxDiv_); this.getDiv().removeChild(d.paneDiv_); this.dragZoom_ = null; } }; /** * Returns true if the drag zoom feature has been enabled. * @return {Boolean} */ google.maps.Map.prototype.keyDragZoomEnabled = function () { return this.dragZoom_ !== null; }; /** * Returns the DragZoom object which is created when google.maps.Map.enableKeyDragZoom is called. * With this object you can use google.maps.event.addListener to attach event listeners * for the 'activate', 'deactivate', 'dragstart', 'drag', and 'dragend' events. * @return {DragZoom} */ google.maps.Map.prototype.getDragZoomObject = function () { return this.dragZoom_; }; })();