File indexing completed on 2025-01-19 03:50:51

0001 /* ============================================================
0002  *
0003  * Date        : 2010-02-05
0004  * Description : JavaScript part of the GoogleMaps-backend for WorldMapWidget2
0005  *
0006  * SPDX-FileCopyrightText: 2010, 2011, 2014 by Michael G. Hansen <mike at mghansen dot de>
0007  * SPDX-FileCopyrightText: 2014 by Justus Schwartz <justus at gmx dot li>
0008  *
0009  * SPDX-License-Identifier: GPL-2.0-or-later
0010  *
0011  * ============================================================ */
0012 
0013 var mapDiv;
0014 var map;
0015 var eventBuffer = new Array();
0016 var markerList = new Object();
0017 var clusterList = new Object();
0018 var clusterDataList = new Object();
0019 var trackList = new Array();
0020 var isInEditMode = false;
0021 var dragMarker;
0022 var dragSnappingToMid = -1;
0023 var dragSnappingToId = -1;
0024 var selectionRectangle;
0025 var temporarySelectionRectangle;
0026 var markers = new Array();
0027 var markerCount = 0;
0028 
0029 // ProjectionHelp: http://taapps-javalibs.blogspot.com/2009/10/google-map-v3how-to-use-overlayviews.html
0030 function ProjectionHelper(overlayMap)
0031 {
0032     google.maps.OverlayView.call(this);
0033     this.setMap(overlayMap);
0034 }
0035 ProjectionHelper.prototype = new google.maps.OverlayView();
0036 ProjectionHelper.prototype.draw = function() { }
0037 var projectionHelper = null;
0038 
0039 function kgeomapPostEventString(eventString)
0040 {
0041     // We keep these 2 lines for backwards compatibility with QWebView
0042     eventBuffer.push(eventString);
0043     window.status = '(event)';
0044 
0045     // We use this when porting to QWebEngineView
0046     console.log('(event)'+eventString);
0047 }
0048 
0049 // We keep this function for backwards compatibility with QWebView
0050 function kgeomapReadEventStrings()
0051 {
0052     var eventBufferString = eventBuffer.join('|');
0053     eventBuffer = new Array();
0054     // let the application know that there are no more events waiting:
0055     window.status = '()';
0056     return eventBufferString;
0057 }
0058 
0059 function kgeomapDebugOut(someString)
0060 {
0061     kgeomapPostEventString('do'+someString);
0062 }
0063 
0064 function kgeomapSetZoom(zoomvalue)
0065 {
0066     map.setZoom(zoomvalue);
0067 }
0068 
0069 function kgeomapGetZoom()
0070 {
0071     return map.getZoom();
0072 }
0073 
0074 function kgeomapGetMaxZoom()
0075 {
0076     return map.mapTypes[map.getMapTypeId()].maxZoom;
0077 }
0078 
0079 function kgeomapGetMinZoom()
0080 {
0081     var minZoom = map.mapTypes[map.getMapTypeId()].minZoom;
0082     if (minZoom==null)
0083     {
0084         minZoom = 1;
0085     }
0086     return minZoom;
0087 }
0088 
0089 function kgeomapZoomIn()
0090 {
0091     map.setZoom(map.getZoom()+1);
0092 }
0093 
0094 function kgeomapZoomOut()
0095 {
0096     map.setZoom(map.getZoom()-1);
0097 }
0098 
0099 function kgeomapSetCenter(lat, lon)
0100 {
0101     var latlng = new google.maps.LatLng(lat, lon);
0102     map.setCenter(latlng);
0103 }
0104 
0105 function kgeomapGetCenter()
0106 {
0107     var latlngString = map.getCenter().toUrlValue(12);
0108     return latlngString;
0109 }
0110 
0111 function kgeomapGetBounds()
0112 {
0113     return map.getBounds().toString();
0114 }
0115 
0116 function kgeomapSetIsInEditMode(state)
0117 {
0118     isInEditMode = state;
0119 }
0120 
0121 function kgeomapLatLngToPoint(latLng)
0122 {
0123     //      There is an offset in fromLatLngToDivPixel once the map has been panned
0124     var myPoint = projectionHelper.getProjection().fromLatLngToDivPixel(latLng);
0125     var centerPoint = projectionHelper.getProjection().fromLatLngToDivPixel(map.getCenter());
0126     var centerOffsetX = Math.floor(mapDiv.offsetWidth / 2);
0127     var centerOffsetY = Math.floor(mapDiv.offsetHeight / 2);
0128     var pointX = myPoint.x-centerPoint.x+centerOffsetX;
0129     var pointY = myPoint.y-centerPoint.y+centerOffsetY;
0130     return new google.maps.Point(pointX, pointY);
0131 }
0132 
0133 function kgeomapLatLngToPixel(lat, lon)
0134 {
0135     //      There is an offset in fromLatLngToDivPixel once the map has been panned
0136     var latlng = new google.maps.LatLng(lat, lon);
0137     var myPoint = projectionHelper.getProjection().fromLatLngToDivPixel(latlng);
0138     var centerPoint = projectionHelper.getProjection().fromLatLngToDivPixel(map.getCenter());
0139     var centerOffsetX = Math.floor(mapDiv.offsetWidth / 2);
0140     var centerOffsetY = Math.floor(mapDiv.offsetHeight / 2);
0141     var pointX = myPoint.x-centerPoint.x+centerOffsetX;
0142     var pointY = myPoint.y-centerPoint.y+centerOffsetY;
0143     return new google.maps.Point(pointX, pointY).toString();
0144 //         return projectionHelper.getProjection().fromLatLngToDivPixel(latlng).toString();
0145 }
0146 
0147 function kgeomapPixelToLatLngObject(x, y)
0148 {
0149     //      There is an offset in fromDivPixelToLatLng once the map has been panned
0150     var centerPoint = projectionHelper.getProjection().fromLatLngToDivPixel(map.getCenter());
0151     var centerOffsetX = mapDiv.offsetWidth / 2;
0152     var centerOffsetY = mapDiv.offsetHeight / 2;
0153     var pointX = x+centerPoint.x-centerOffsetX;
0154     var pointY = y+centerPoint.y-centerOffsetY;
0155     var point = new google.maps.Point(pointX, pointY);
0156     return projectionHelper.getProjection().fromDivPixelToLatLng(point);
0157 }
0158 
0159 function kgeomapPixelToLatLng(x, y)
0160 {
0161     return kgeomapPixelToLatLngObject(x, y).toUrlValue(12);
0162 }
0163 
0164 // parameter: "SATELLITE"/"ROADMAP"/"HYBRID"/"TERRAIN"
0165 function kgeomapSetMapType(newMapType)
0166 {
0167     if (newMapType == "SATELLITE") { map.setMapTypeId(google.maps.MapTypeId.SATELLITE); }
0168     if (newMapType == "ROADMAP")   { map.setMapTypeId(google.maps.MapTypeId.ROADMAP); }
0169     if (newMapType == "HYBRID")    { map.setMapTypeId(google.maps.MapTypeId.HYBRID); }
0170     if (newMapType == "TERRAIN")   { map.setMapTypeId(google.maps.MapTypeId.TERRAIN); }
0171 }
0172 
0173 function kgeomapGetMapType()
0174 {
0175     var myMapType = map.getMapTypeId();
0176     if (myMapType == google.maps.MapTypeId.SATELLITE) { return "SATELLITE"; }
0177     if (myMapType == google.maps.MapTypeId.ROADMAP )  { return "ROADMAP"; }
0178     if (myMapType == google.maps.MapTypeId.HYBRID )   { return "HYBRID"; }
0179     if (myMapType == google.maps.MapTypeId.TERRAIN )  { return "TERRAIN"; }
0180     return "";
0181 }
0182 
0183 function kgeomapSetShowMapTypeControl(state)
0184 {
0185     var myOptions = {
0186             mapTypeControl: state
0187         }
0188     map.setOptions(myOptions);
0189 }
0190 
0191 function kgeomapSetShowNavigationControl(state)
0192 {
0193     var myOptions = {
0194             navigationControl: state
0195         }
0196     map.setOptions(myOptions);
0197 }
0198 
0199 function kgeomapSetShowScaleControl(state)
0200 {
0201     var myOptions = {
0202             scaleControl: state
0203         }
0204     map.setOptions(myOptions);
0205 }
0206 
0207 function kgeomapClearMarkers(mid)
0208 {
0209     for (var i in markerList[mid])
0210     {
0211         markerList[mid][i].marker.setMap(null);
0212     }
0213     markerList[mid] = new Object();
0214 }
0215 
0216 function kgeomapClearTracks() 
0217 {
0218     for (var i in trackList) {
0219         trackList[i].track.setMap(null);
0220     }
0221     trackList = new Array();
0222 
0223     return true;
0224 }
0225 
0226 function kgeomapGetTrackIndex(tid)
0227 {
0228     for (var i=0; i<trackList.length; ++i)
0229     {
0230         if (trackList[i].id==tid)
0231         {
0232             return i;
0233         }
0234     }
0235 
0236     return -1;
0237 }
0238 
0239 function kgeomapRemoveTrack(tid)
0240 {
0241     var idx = kgeomapGetTrackIndex(tid);
0242     if (idx<0)
0243     {
0244         return;
0245     }
0246 
0247     trackList[idx].track.setMap(null);
0248     trackList.splice(idx, 1);
0249 }
0250 
0251 function kgeomapCreateTrack(tid, trackColor)
0252 {
0253     // trackColor has to have the form '#FF0000'
0254     var oldIndex = kgeomapGetTrackIndex(tid);
0255     if (oldIndex>=0)
0256     {
0257         trackList[oldIndex].track.setMap(null);
0258         trackList.splice(oldIndex, 1);
0259     }
0260 
0261     var trackEntry = new Object();
0262     trackEntry.id = tid;
0263     trackEntry.track = new google.maps.Polyline({
0264             geodesic: true,
0265             strokeColor: trackColor,
0266             strokeOpacity: 1.0,
0267             strokeWeight: 2
0268         });
0269 
0270     trackList.push(trackEntry);
0271 
0272     return trackList.length-1;
0273 }
0274 
0275 function kgeomapAddToTrack(tid, coordString)
0276 {
0277     var trackIndex = kgeomapGetTrackIndex(tid);
0278     if (trackIndex<0)
0279     {
0280         return false;
0281     }
0282 
0283     var track = trackList[trackIndex].track;
0284     /// @TODO Does setting and unsetting the map take long? Maybe it is better
0285     ///       to create, add points, then add map instead.
0286 //    track.setMap(null); // See bug #342427
0287 
0288     var trackCoordinates = track.getPath();
0289 //     for (var i = 0; i < coordString.length; i+=2)
0290 //     {
0291 //         var cLat = coordString[i];
0292 //         var cLon = coordString[i+1];
0293 //         trackCoordinates.push(new google.maps.LatLng(cLat,cLon));
0294 //     }
0295     var coordArray = JSON.parse(coordString);
0296     for (var i = 0; i < coordArray.length; ++i)
0297     {
0298         var coord = coordArray[i];
0299         trackCoordinates.push(new google.maps.LatLng(coord.lat,coord.lon));
0300     }
0301     track.setPath(trackCoordinates);
0302     track.setMap(map);
0303     trackList[trackIndex].track = track;
0304 
0305     return true;
0306 }
0307 
0308 function kgeomapSetMarkerPixmap(mid, id, pixmapWidth, pixmapHeight, xOffset, yOffset, pixmapurl)
0309 {
0310     var pixmapSize = new google.maps.Size(pixmapWidth, pixmapHeight);
0311     var pixmapOrigin = new google.maps.Point(0, 0);
0312     var anchorPoint = new google.maps.Point(xOffset, yOffset);
0313     var markerImage = new google.maps.MarkerImage(pixmapurl, pixmapSize, pixmapOrigin, anchorPoint);
0314     markerList[mid][id].marker.setIcon(markerImage);
0315 }
0316 
0317 function kgeomapAddMarker(mid, id, lat, lon, setDraggable, setSnaps)
0318 {
0319     var latlng = new google.maps.LatLng(lat, lon);
0320     var marker = new google.maps.Marker({
0321             position: latlng,
0322             map: map,
0323             draggable: setDraggable,
0324             icon: new google.maps.MarkerImage('marker-green.png', new google.maps.Size(20, 32)),
0325             zIndex: 10
0326         });
0327 
0328     google.maps.event.addListener(marker, 'dragend', function()
0329         {
0330             kgeomapPostEventString('mm'+id.toString());
0331         });
0332     if (!markerList[mid])
0333     {
0334         markerList[mid] = new Object();
0335     }
0336     markerList[mid][id] = {
0337             marker: marker,
0338             snaps: setSnaps
0339         };
0340 }
0341 
0342 function kgeomapGetMarkerPosition(mid,id)
0343 {
0344     var latlngString;
0345     if (markerList[mid.toString()][id.toString()])
0346     {
0347         latlngString = markerList[mid.toString()][id.toString()].marker.getPosition().toUrlValue(12);
0348     }
0349     return latlngString;
0350 }
0351 
0352 function kgeomapClearClusters()
0353 {
0354     for (var i in clusterList)
0355     {
0356         clusterList[i].setMap(null);
0357     }
0358     clusterList = new Object();
0359     clusterDataList = new Object();
0360 }
0361 
0362 function kgeomapGetPixmapName(markerCount, markerSelectedCount)
0363 {
0364     var colorCode;
0365     if (markerCount>=100)
0366     {
0367         colorCode="ff0000";
0368     }
0369     else if (markerCount>=50)
0370     {
0371         colorCode="ff7f00";
0372     }
0373     else if (markerCount>=10)
0374     {
0375         colorCode="ffff00";
0376     }
0377     else if (markerCount>=2)
0378     {
0379         colorCode="00ff00";
0380     }
0381     else
0382     {
0383         colorCode="00ffff";
0384     }
0385     if (markerSelectedCount==markerCount)
0386     {
0387         colorCode+="-selected";
0388     }
0389     else if (markerSelectedCount>0)
0390     {
0391         colorCode+="-someselected";
0392     }
0393     return colorCode;
0394 }
0395 
0396 function kgeomapSetClusterPixmap(id, pixmapWidth, pixmapHeight, xOffset, yOffset, pixmapurl)
0397 {
0398     var pixmapSize = new google.maps.Size(pixmapWidth, pixmapHeight);
0399     var pixmapOrigin = new google.maps.Point(0, 0);
0400     var anchorPoint = new google.maps.Point(xOffset, yOffset);
0401     var markerImage = new google.maps.MarkerImage(pixmapurl, pixmapSize, pixmapOrigin, anchorPoint);
0402     clusterList[id].setIcon(markerImage);
0403 }
0404 
0405 function kgeomapAddCluster(id, lat, lon, setDraggable, markerCount, markerSelectedCount)
0406 {
0407     var latlng = new google.maps.LatLng(lat, lon);
0408     var clusterIcon;
0409     var colorCode = kgeomapGetPixmapName(markerCount, markerSelectedCount);
0410     if (isInEditMode)
0411     {
0412         clusterIcon = new google.maps.MarkerImage('marker-'+colorCode+'.png', new google.maps.Size(20, 32));
0413     } else
0414     {
0415         clusterIcon = new google.maps.MarkerImage('cluster-circle-'+colorCode+'.png', new google.maps.Size(30, 30), new google.maps.Point(0,0), new google.maps.Point(15, 15));
0416     }
0417     var marker = new google.maps.Marker({
0418             position: latlng,
0419             map: map,
0420             draggable: isInEditMode,
0421             icon: clusterIcon,
0422             zIndex: 10
0423         });
0424 
0425 /*        for (var mid in markerList) {
0426             for (var id in markerList[mid]) {
0427                 markerList[mid][id].marker.setClickable(false);
0428             }
0429         }
0430 */
0431 
0432     google.maps.event.addListener(marker, 'dragstart', function()
0433         {
0434             var movingClusterData = clusterDataList[id];
0435             if (movingClusterData.MarkerSelectedCount==0)
0436             {
0437                 // no need to change the cluster in any way
0438                 return;
0439             }
0440             // at least some items in the cluster are selected. we have to scan all clusters and
0441             // take their selected markers:
0442             var newSelectedCount = 0;
0443             for (var i in clusterList)
0444             {
0445                 var clusterData = clusterDataList[i];
0446                 if (clusterData.MarkerSelectedCount>0)
0447                 {
0448                     newSelectedCount+=clusterData.MarkerSelectedCount;
0449                     var newMarkerCount = clusterData.MarkerCount-clusterData.MarkerSelectedCount;
0450 
0451                     if (i!=id)
0452                     {
0453                         var colorCode = kgeomapGetPixmapName(newMarkerCount, 0);
0454                         var clusterIcon = new google.maps.MarkerImage('marker-'+colorCode+'.png', new google.maps.Size(20, 32));
0455                         clusterList[i].setOptions({ icon: clusterIcon, title: newMarkerCount.toString() });
0456                     }
0457                 }
0458             }
0459             // adjust the moving marker
0460             var colorCode = kgeomapGetPixmapName(newSelectedCount, newSelectedCount);
0461             var clusterIcon = new google.maps.MarkerImage('marker-'+colorCode+'.png', new google.maps.Size(20, 32));
0462             clusterList[id].setOptions({ icon: clusterIcon, title: newSelectedCount.toString()});
0463 
0464             // create a leftover-marker:
0465             var leftOverMarkerCount=movingClusterData.MarkerCount-movingClusterData.MarkerSelectedCount;
0466             if (leftOverMarkerCount>0)
0467             {
0468                 var colorCode = kgeomapGetPixmapName(leftOverMarkerCount, 0);
0469                 var clusterIcon = new google.maps.MarkerImage('marker-'+colorCode+'.png', new google.maps.Size(20, 32));
0470                 var leftOverMarker = new google.maps.Marker({
0471                         position: latlng,
0472                         map: map,
0473                         icon: clusterIcon,
0474                         title: leftOverMarkerCount.toString(),
0475                         zIndex: 10
0476                     });
0477                 clusterList[-1]=leftOverMarker;
0478             }
0479         });
0480     google.maps.event.addListener(marker, 'drag', function(e)
0481         {
0482             // get the pixel position:
0483             var clusterPoint = kgeomapLatLngToPoint(e.latLng);
0484             // now iterate through all markers to which we can snap
0485             var minDistSquared=-1;
0486             var minMid;
0487             var minId;
0488             kgeomapDebugOut('drag');
0489             for (var mid in markerList)
0490             {
0491                 for (var id in markerList[mid])
0492                 {
0493                     if (!markerList[mid][id].snaps)
0494                     {
0495                         continue;
0496                     }
0497 
0498                     var markerPoint = kgeomapLatLngToPoint(markerList[mid][id].marker.getPosition());
0499                     var distanceSquared = (clusterPoint.x-markerPoint.x)*(clusterPoint.x-markerPoint.x) + (clusterPoint.y-markerPoint.y)*(clusterPoint.y-markerPoint.y);
0500                     if ((distanceSquared<=100)&&((minDistSquared<0)||(distanceSquared<minDistSquared)))
0501                     {
0502                         minDistSquared = distanceSquared;
0503                         minMid = mid;
0504                         minId = id;
0505                     }
0506                 }
0507             }
0508             if (minDistSquared>=0)
0509             {
0510                 // TODO: emit proper snap signal
0511                 marker.setPosition(markerList[minMid][minId].marker.getPosition());
0512                 dragSnappingToId = minId;
0513                 dragSnappingToMid = minMid;
0514             }
0515             else
0516             {
0517                 dragSnappingToId = -1;
0518                 dragSnappingToMid = -1;
0519             }
0520         });
0521     google.maps.event.addListener(marker, 'dragend', function()
0522         {
0523             if (dragSnappingToMid>=0)
0524             {
0525                 kgeomapPostEventString('cs'+id.toString()+'/'+dragSnappingToMid.toString()+'/'+dragSnappingToId.toString());
0526             }
0527             else
0528             {
0529                 kgeomapPostEventString('cm'+id.toString());
0530             }
0531         });
0532     google.maps.event.addListener(marker, 'click', function()
0533         {
0534             kgeomapPostEventString('cc'+id.toString());
0535         });
0536     
0537     clusterList[id] = marker;
0538     var clusterData = new Object();
0539     clusterData["MarkerCount"]=markerCount;
0540     clusterData["MarkerSelectedCount"]=markerSelectedCount;
0541     clusterDataList[id]=clusterData;
0542 }
0543 
0544 function kgeomapGetClusterPosition(id)
0545 {
0546     var latlngString;
0547     if (clusterList[id.toString()])
0548     {
0549         latlngString = clusterList[id.toString()].getPosition().toUrlValue(12);
0550     }
0551     return latlngString;
0552 }
0553 
0554 function kgeomapWidgetResized(newWidth, newHeight)
0555 {
0556     document.getElementById('map_canvas').style.height=newHeight.toString()+'px';
0557 }
0558 
0559 function kgeomapRemoveDragMarker()
0560 {
0561     if (dragMarker)
0562     {
0563         dragMarker.setMap(null);
0564         dragMarker = null;
0565     }
0566 }
0567 
0568 function kgeomapMoveDragMarker(x, y)
0569 {
0570     if (dragMarker)
0571     {
0572         dragMarker.setPosition(kgeomapPixelToLatLngObject(x ,y));
0573     }
0574 }
0575 
0576 function kgeomapSetDragMarker(x, y, markerCount, markerSelectedCount)
0577 {
0578     kgeomapRemoveDragMarker();
0579     var latlng = kgeomapPixelToLatLngObject(x, y);
0580     var colorCode = kgeomapGetPixmapName(markerCount, markerSelectedCount);
0581     var clusterIcon = new google.maps.MarkerImage('marker-'+colorCode+'.png', new google.maps.Size(20, 32));
0582     dragMarker = new google.maps.Marker({
0583             position: latlng,
0584             map: map,
0585             icon: clusterIcon
0586         });
0587 }
0588 
0589 function kgeomapUpdateSelectionRectangleColor()
0590 {
0591     if (selectionRectangle == null)
0592     {
0593         return;
0594     }
0595 
0596     if (temporarySelectionRectangle == null)
0597     {
0598         selectionRectangle.setOptions({
0599                     fillOpacity : 0.0,
0600                     strokeColor : "#0000ff",
0601                     strokeWeight: 1
0602                 });
0603     }
0604     else
0605     {
0606         selectionRectangle.setOptions({
0607                     fillOpacity : 0.0,
0608                     strokeColor : "#ff0000",
0609                     strokeWeight: 1
0610                 });
0611     }
0612 }
0613 
0614 function kgeomapSetSelectionRectangle(west, north, east, south)
0615 {
0616     var firstSelectionPoint = new google.maps.LatLng(south,west,true);
0617     var secondSelectionPoint = new google.maps.LatLng(north,east,true);
0618 
0619     latLngBounds = new google.maps.LatLngBounds(
0620                     firstSelectionPoint,
0621                     secondSelectionPoint
0622                 );
0623 
0624     if (selectionRectangle == null)
0625     {
0626         selectionRectangle = new google.maps.Rectangle({
0627                     bounds: latLngBounds,
0628                     clickable: false,
0629                     fillOpacity: 0.0,
0630                     map: map,
0631                     strokeColor: "#0000FF",
0632                     strokeWeight: 1,
0633                     zIndex: 100
0634                 });
0635     }
0636     else
0637     {
0638         selectionRectangle.setOptions({
0639                     bounds: latLngBounds,
0640                     fillOpacity : 0.0,
0641                     strokeColor : "#FF0000",
0642                     strokeWeight: 1
0643                 });
0644     }
0645 
0646     kgeomapUpdateSelectionRectangleColor();
0647 }
0648 
0649 
0650 function kgeomapSetTemporarySelectionRectangle(west, north, east, south)
0651 {
0652     var firstPoint = new google.maps.LatLng(south,west,true);
0653     var secondPoint = new google.maps.LatLng(north,east,true);
0654 
0655     var latLngBounds = new google.maps.LatLngBounds(
0656             firstPoint,
0657             secondPoint
0658         );
0659 
0660     if (temporarySelectionRectangle == null)
0661     {
0662         temporarySelectionRectangle = new google.maps.Rectangle({
0663                     bounds: latLngBounds,
0664                     clickable: false,
0665                     fillOpacity: 0.0,
0666                     map: map,
0667                     strokeColor: "#0000FF",
0668                     strokeWeight: 1,
0669                     zIndex: 100
0670                 });
0671     }
0672     else
0673     {
0674        temporarySelectionRectangle.setOptions({
0675                     bounds: latLngBounds,
0676                     fillOpacity : 0.0,
0677                     strokeColor : "#0000FF",
0678                     strokeWeight: 1
0679                 });
0680     }
0681 
0682     kgeomapUpdateSelectionRectangleColor();
0683 }
0684 
0685 function kgeomapRemoveSelectionRectangle()
0686 {
0687     if (!selectionRectangle)
0688     {
0689         return;
0690     }
0691 
0692     selectionRectangle.setMap(null);
0693     selectionRectangle = null;
0694 }
0695 
0696 function kgeomapRemoveTemporarySelectionRectangle()
0697 {
0698     if (!temporarySelectionRectangle)
0699     {
0700         return;
0701     }
0702 
0703     temporarySelectionRectangle.setMap(null);
0704     temporarySelectionRectangle = null;
0705 
0706     kgeomapUpdateSelectionRectangleColor();
0707 }
0708 
0709 function kgeomapSelectionModeStatus(state)
0710 {
0711     map.draggable = !state;
0712 
0713     if (!state)
0714     {
0715         kgeomapRemoveTemporarySelectionRectangle();
0716     }
0717 }
0718 
0719 function kgeomapSetMapBoundaries(west, north, east, south, useSaneZoomLevel)
0720 {
0721     firstPoint = new google.maps.LatLng(south, west, true);
0722     secondPoint = new google.maps.LatLng(north, east, true);
0723 
0724     newBounds = new google.maps.LatLngBounds(firstPoint, secondPoint);
0725     map.fitBounds(newBounds);
0726 
0727     if (useSaneZoomLevel && (map.getZoom()>17))
0728     {
0729         map.setZoom(17);
0730     }
0731 }
0732 
0733 function kgeomapInitialize()
0734 {
0735     var latlng = new google.maps.LatLng(52.0, 6.0);
0736     var myOptions = {
0737             zoom: 8,
0738             center: latlng,
0739             mapTypeId: google.maps.MapTypeId.ROADMAP
0740         };
0741     mapDiv = document.getElementById("map_canvas");
0742     //       mapDiv.style.height="100%"
0743     map = new google.maps.Map(mapDiv, myOptions);
0744     google.maps.event.addListener(map, 'maptypeid_changed', function()
0745         {
0746             kgeomapPostEventString('MT'+kgeomapGetMapType());
0747         });
0748 
0749     //google.maps.event.clearListeners(map, 'dragstart');
0750     //google.maps.event.clearListeners(map, 'drag');
0751     //google.maps.event.clearListeners(map, 'dragend');
0752     //google.maps.event.clearInstanceListeners(map);
0753 
0754     //  these are too heavy on the performance. monitor 'idle' event only for now:
0755     //       google.maps.event.addListener(map, 'bounds_changed', function() {
0756     //           kgeomapPostEventString('MB');
0757     //       });
0758     google.maps.event.addListener(map, 'zoom_changed', function()
0759         {
0760             kgeomapPostEventString('ZC');
0761         });
0762     google.maps.event.addListener(map, 'idle', function()
0763         {
0764             kgeomapPostEventString('id');
0765         });
0766     // source: http://taapps-javalibs.blogspot.com/2009/10/google-map-v3how-to-use-overlayviews.html
0767     projectionHelper = new ProjectionHelper(map);
0768 }