2016-02-26 60 views
0

我正在從Google地圖項目中進行工作,在那裏我使用從數據庫讀取的標記(drawMarkers函數)填充Google地圖。隨着谷歌地圖發現你的當前位置,並保持刷新它每隔幾秒鐘,以保持跟蹤你在地圖上。我的問題是,有一個var最接近這也是我正在使用的函數也找到最接近的標記,然後從那裏創建方向到當前位置。我不知道如何找到最接近的標記,所以我從堆棧溢出的另一個問題中借用了代碼,並試圖將其應用於此項目。我需要幫助讓我最親近的功能找到最接近的標記,然後讓它目的地的方向服務在谷歌地圖API中使用方向服務

$ionicSideMenuDelegate.canDragContent(false); 

$scope.getTourMarkers = function() { 
    tourmarkers.getTourMarkers().success(function (data) { 
     $scope.tourmarkers = data; 
     console.log($scope.tourmarkers); 
     drawMarkers(); 
    }); 
}; 


var drawMarkers = function() { 

    var markers; 
    var content; 
    var infoWindow; 


    for (var i = 0; i < $scope.tourmarkers.length; i++) { 
     content = '<h2>' + $scope.tourmarkers[i].title + '</h2>' + 
      '<br />' + 
      '<p>' + 

      '</p>'; 

     infoWindow = new google.maps.InfoWindow({ 
      content: content 
     }); 

     var point = new google.maps.LatLng($scope.tourmarkers[i].lat, $scope.tourmarkers[i].lon); 

     markers = new google.maps.Marker({ 
      label: "S", 
      animation: google.maps.Animation.DROP, 
      position: point, 
      map: map, 
      info: content 
    }); 

     //SCOPE: 'this' refers to the current 'markers' object, we pass in the info and marker 
     google.maps.event.addListener(markers, 'click', function() { 
      infoWindow.setContent(this.info); 
      infoWindow.open(map, this); 
     }); 
    } 

}; 

var myLatlng = new google.maps.LatLng(38.5602, -121.4241); 
var NAPA_HALL_LAT_LNG = new google.maps.LatLng(38.553801, -121.4212745); // just created this marker for testing purposes 

var mapOptions = { 
    center: myLatlng, 
    zoom: 18, 
    mapTypeId: google.maps.MapTypeId.ROADMAP, 
    zoomControl: true, 
    disableDefaultUI: true 
}; 

var map = new google.maps.Map(document.getElementById("map"), mapOptions); 

var marker = new google.maps.Marker({ 
    position: myLatlng, 
    map: map, 
    title: 'SAC STATE' 
}); 

var dest = new google.maps.Marker({ 
    position: NAPA_HALL_LAT_LNG, 
    map: map, 
    title: 'NAPA HALL' 
}); 

///////////////////Directions Display////////////////////// 
var directionsDisplay = new google.maps.DirectionsRenderer; 
var directionsService = new google.maps.DirectionsService; 


////////////////////////////////////////////////////////////////////////////////////////// 
//Goal of this function is to find closest marker to current location 
//then to create directions to that marker. 
//should be refreshed everytime in the onSuccess function 
var closest = function (directionsService, directionsDisplay, marker, dest) { 

    var event; 

    function rad(x) {return x*Math.PI/180;} 

    function find_closest_marker(event) { 
     var lat = event.latLng.lat(); 
     var lng = event.latLng.lng(); 
     var R = 6371;       // radius of earth in km 
     var distances = []; 
     var shortest = -1; 


     for(i=0;i < $scope.tourmarkers.length; i++) { 
     content = '<h2>' + $scope.tourmarkers[i].title + '</h2>' + 
      '<br />' + 
      '<p>' + 

      '</p>'; 

     infoWindow = new google.maps.InfoWindow({ 

     var mlat = $scope.tourmarkers[i].position.lat(); 
     var mlng = $scope.tourmarkers[i].position.lng(); 
     var dLat = rad(mlat - lat); 
     var dLong = rad(mlng - lng); 
     var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2); 
     var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
     var d = R * c; 
     distances[i] = d; 
     if (shortest == -1 || d < distances[shortest]) { 
      shortest = i; 
     } 
    } 

    alert(map.markers[shortest].title); 
} 

    /////**directions feature should have the closest marker be the desitination// 
    directionsService.route({ 
     origin: marker.position, 
     destination: dest.position,    // i think the marker that should in here is shortest. 
     travelMode: google.maps.TravelMode.WALKING 
    }, function(response,status) { 
     if(status==google.maps.DirectionsStatus.OK) { 
      directionsDisplay.setDirections(response); 
     } else { 
      window.alert('Directions request failed due to ' + status); 
     } 
    }); 
}; 
////////////////////////////////////////////////////////////////////////////////////////// 

var onSuccess = function (position) { 

    marker.setPosition(new google.maps.LatLng(position.coords.latitude, position.coords.longitude)); 
    directionsDisplay.setMap(map); 
    dest.setPosition(new google.maps.LatLng(38.553801, -121.4212745)); 
    //dest.setPosition((closest(marker, $scope.tourmarkers)).position); // if you can get this line to work without commenting it out then you're set 
    closest(directionsService,directionsDisplay, marker,dest); 
    $scope.map = map; 
    //$scope.map.panTo(new google.maps.LatLng(position.coords.latitude, position.coords.longitude)); 
}; 

function onError(error) { 
    alert('code: ' + error.code + '\n' + 
     'message: ' + error.message + '\n'); 
} 

navigator.geolocation.watchPosition(onSuccess, onError, { 
    maximumAge: 3000, 
    timeout: 5000, 
    enableHighAccuracy: true 
}); 

一切都在這個項目中工作正常,除了最接近的功能。但即使如此,我已經測試了方向服務,甚至也在工作。我只需要幫助,使方向服務中的目的地成爲與當前位置最接近的標記。

回答

0

我覺得這個代碼是對你有幫助我在我的項目中使用此代碼,這樣您的要求同我的要求

在下面的函數「數據」是指緯度經度的從服務器列表

function initialize(data) { 
    size = 0; 
    counts = 0; 
    stops = data; 
    size = stops.length; 

     if (stops.length > 0) { 
      var map = new window.google.maps.Map(document 
        .getElementById("map")); 
      // new up complex objects before passing them around 
      var directionsDisplay = new window.google.maps.DirectionsRenderer(
        { 
         suppressMarkers : true, 
         polylineOptions : { 
          strokeColor : "black" 
         } 
        }); 
      var directionsService = new window.google.maps.DirectionsService(); 
      Tour_startUp(stops); 
      window.tour.loadMap(map, directionsDisplay); 
      window.tour.fitBounds(map,stops); 
      /* if (stops.length > 1) */ 
       window.tour.calcRoute(stops,directionsService, 
         directionsDisplay,size); 
     } 
} 


function Tour_startUp(stops) { 
    var stops=stops; 
    var counts=0; 
    if (!window.tour) window.tour = { 
     // map: google map object 
     // directionsDisplay: google directionsDisplay object (comes in empty) 
     loadMap: function (map, directionsDisplay) { 
      var myOptions = { 
       zoom:10, 
       center: new window.google.maps.LatLng(17.379818, 78.478542), // default to Hyderabad 
       mapTypeId: window.google.maps.MapTypeId.ROADMAP 
      }; 
      map.setOptions(myOptions); 
      directionsDisplay.setMap(map); 
     }, 
     fitBounds: function (map,stops) { 
      var bounds = new window.google.maps.LatLngBounds(); 
      // extend bounds for each record 

      jQuery.each(stops, function (key, val) { 
       var myLatlng = new window.google.maps.LatLng(val.latitude, val.longitude); 
       bounds.extend(myLatlng); 
      }); 
      map.fitBounds(bounds); 

     }, 
     calcRoute: function (stops,directionsService, directionsDisplay,size) { 
      size=size; 
      var batches = []; 
      var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints 
      var itemsCounter = 0; 
      var wayptsExist = stops.length > 0; 
      var tempp=0; 
      while (wayptsExist) { 
       var subBatch = []; 
       var subitemsCounter = 0; 

       for (var j = itemsCounter; j < stops.length; j++) { 
        subitemsCounter++; 
        tempp++; 
        subBatch.push({ 

         location: new window.google.maps.LatLng(stops[j].latitude, stops[j].longitude), 
         stopover: true 
        }); 
        if (subitemsCounter == itemsPerBatch) 
         break; 
       } 
       itemsCounter += subitemsCounter; 
       batches.push(subBatch); 
       wayptsExist = itemsCounter < stops.length; 
       // If it runs again there are still points. Minus 1 before continuing to 
       // start up with end of previous tour leg 
       itemsCounter--; 
      } 

      // now we should have a 2 dimensional array with a list of a list of waypoints 
      var combinedResults; 
      var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort 
      var directionsResultsReturned = 0; 

      for (var k = 0; k < batches.length; k++) { 
       var lastIndex = batches[k].length - 1; 
       var start = batches[k][0].location; 
       //delay(600); 
       var end = batches[k][lastIndex].location; 


       // trim first and last entry from array 
       var waypts = []; 
       waypts = batches[k]; 
       waypts.splice(0, 1); 
       waypts.splice(waypts.length - 1, 1); 

       var request = { 
        origin: start, 
        destination: end, 
        waypoints: waypts, 
        travelMode: window.google.maps.TravelMode.WALKING 
       }; 
       (function (kk) { 
        directionsService.route(request, function (result, status) { 
         if (status == window.google.maps.DirectionsStatus.OK) { 
          var unsortedResult = { order: kk, result: result }; 
          unsortedResults.push(unsortedResult); 
          //alert("count test"); 
          directionsResultsReturned++; 
          if (directionsResultsReturned == batches.length) // we've received all the results. put to map 
          { 
           // sort the returned values into their correct order 
           unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); }); 
           var count = 0; 
           for (var key in unsortedResults) { 
            if (unsortedResults[key].result != null) { 
             if (unsortedResults.hasOwnProperty(key)) { 
              if (count == 0) // first results. new up the combinedResults object 
               combinedResults = unsortedResults[key].result; 
              else { 
               // only building up legs, overview_path, and bounds in my consolidated object. This is not a complete 
               // directionResults object, but enough to draw a path on the map, which is all I need 
               combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs); 
               combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path); 

               combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast()); 
               combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest()); 
              } 
              count++; 
             } 
            } 
           } 
           directionsDisplay.setDirections(combinedResults); 
           var legs = combinedResults.routes[0].legs; 
           var summaryPanel = document.getElementById('directions_panel'); 
           summaryPanel.innerHTML = ''; 
           var totdist=0; 
           for (var i=0; i < legs.length;i++){ 

            var markerletter = "A".charCodeAt(0); 
            var markerletter2= "B".charCodeAt(0) 
             markerletter += i; 
            markerletter2 += i; 
            markerletter = String.fromCharCode(markerletter); 
            markerletter2 = String.fromCharCode(markerletter2); 
            createMarker(directionsDisplay.getMap(),legs[i].start_location,legs[i].start_address,markerletter,size);//To display location address on the marker 
            var routeSegment = i + 1; 
            var point=+routeSegment+1; 
            summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + '</b><br>'; 
            summaryPanel.innerHTML += '<b>Point '+ routeSegment +' :</b>'+ ' ' +legs[i].start_address + ' <br> '; 
            summaryPanel.innerHTML += '<b>Point '+ point +' :</b>'+ ' '+legs[i].end_address + '<br>'; 
            summaryPanel.innerHTML += '<b>Distance Covered '+' :</b>'+legs[i].distance.text + '<br><br>'; 
            var test=legs[i].distance.text.split(' '); 
            var one=parseFloat(test[0]); 
           if(test[1]=="m"){ 
            var one=parseFloat(test[0]/1000); 
            } 
            totdist=parseFloat(totdist)+parseFloat(one); 
           } 
           summaryPanel.innerHTML += '<b> Total Distance :'+totdist + 'km'+ '</b><br><br>'; 
           var i=legs.length; 
           var markerletter = "A".charCodeAt(0); 
        markerletter += i; 
           markerletter = String.fromCharCode(markerletter); 
           createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,legs[legs.length-1].end_address,markerletter,size); 
          } 
         } 
        }); 
       })(k); 
       function delay(ms) { 
         ms += new Date().getTime(); 
         while (new Date() < ms){} 
        } 
      } 
     }//calculate route end 
    }; 
} 



//to show information on clicking marker 
var infowindow = new google.maps.InfoWindow(
    { 
    size: new google.maps.Size(150,50) 
    }); 


var icons = new Array(); 
icons["red"] = new google.maps.MarkerImage("mapIcons/marker_red.png", 
     // This marker is 20 pixels wide by 34 pixels tall. 
     new google.maps.Size(20, 34), 
     // The origin for this image is 0,0. 
     new google.maps.Point(0,0), 
     // The anchor for this image is at 9,34. 
     new google.maps.Point(9, 34)); 



function getMarkerImage(iconStr,size) { 
    counts++; 
    if(counts==size){ 
     var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/blue.png"; 
     counts = 0; 
    }else{ 
    if (iconStr=="undefined") { 
     iconStr = "red"; 
     var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/red.png"; 
    } 
    else{ 
     var markerimageLoc="http://www.google.com/mapfiles/marker"+ iconStr +".png"; 
     // var markerimageLoc = "http://www.maps.google.com/mapfiles/ms/icons/red.png"; 
    } 
    } 
     icons[iconStr] = new google.maps.MarkerImage(markerimageLoc, 
     // This marker is 20 pixels wide by 34 pixels tall. 
     new google.maps.Size(25, 34), 
     // The origin for this image is 0,0. 
     new google.maps.Point(0,0), 
     // The anchor for this image is at 6,20. 
     new google.maps.Point(9, 34)); 
    return icons[iconStr]; 

} 
    // Marker sizes are expressed as a Size of X,Y 
    // where the origin of the image (0,0) is located 
    // in the top left of the image. 

    // Origins, anchor positions and coordinates of the marker 
    // increase in the X direction to the right and in 
    // the Y direction down. 

    var iconShadow = new google.maps.MarkerImage('http://www.google.com/mapfiles/shadow50.png', 
     // The shadow image is larger in the horizontal dimension 
     // while the position and offset are the same as for the main image. 
     new google.maps.Size(37, 34), 
     new google.maps.Point(0,0), 
     new google.maps.Point(9, 34)); 
     // Shapes define the clickable region of the icon. 
     // The type defines an HTML &lt;area&gt; element 'poly' which 
     // traces out a polygon as a series of X,Y points. The final 
     // coordinate closes the poly by connecting to the first 
     // coordinate. 
    var iconShape = { 
     coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0], 
     type: 'poly' 
    }; 

function createMarker(map, latlng, label, character,size) { 
     var markerletter = character; 
     var size=size; 
     if (/[^a-zA-Z]/.test(character)) { 
      var markerletter = "undefined"; 
     } 
     var contentString = '<b>' + label + '</b><br>'; 
     var marker = new google.maps.Marker({ 
      position : latlng, 
      map : map, 
      shadow : iconShadow, 
      icon : getMarkerImage(markerletter,size), 
      shape : iconShape, 
      title : label, 
      zIndex : Math.round(latlng.lat() * -100000) << 5 
     }); 
     marker.myname = label; 

     google.maps.event.addListener(marker, 'click', function() { 
      infowindow.setContent(contentString); 
      infowindow.open(map, marker); 
     }); 
     return marker; 
    }