0

I'm trying to make a origin and destination menu, so the user will choose the locations in each input, and each input will add a marker to the map and then it will calculate the distance, this is my progress so far: I've successfully added a map with a search box, but I can't create another one and I don't know how to do this.

This is my code:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=places"></script>
<div style="background-color: #FFC012">
<input type="text" id="orign" placeholder="origin">
<input type="text" id="destn" placeholder="destination">
<br>
<div id="map-canvas">
    <script>

var map = new google.maps.Map(document.getElementById('map-canvas'),{
  center:{
     lat: 19.4978,
     lng: -99.1269
 },
 zoom:15
 });

 var marker = new google.maps.Marker({
 map:map,
 draggable: false
 });


 if (navigator.geolocation) {
 navigator.geolocation.getCurrentPosition(function (position) {
   initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
   map.setCenter(initialLocation);
   /*marker.setPosition(initialLocation);         */
 });
 }


var searchBox = new google.maps.places.SearchBox(document.getElementById('orign'));

google.maps.event.addListener(searchBox, 'places_changed',function(){

var places = searchBox.getPlaces();

var bounds = new google.maps.LatLngBounds();
var i, place;

for(i=0; place=places[i];i++){
  bounds.extend(place.geometry.location);
  marker.setPosition(place.geometry.location);
}
map.fitBounds(bounds);
map.setZoom(15);
})



</script>
</div>
</div>
evan
  • 5,443
  • 2
  • 11
  • 20
  • Related example in the documentation: https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/places-autocomplete-directions – geocodezip Nov 23 '19 at 14:37

1 Answers1

1

One option would be to start from the Autocomplete Directions Example in the documentation, change the Autocomplete objects to SearchBox objects, and the associated code to account for the differences (SearchBox has a places_changed event, Autocomplete has place_changed (singular); the routine to get the results also has a different name (singular vs. plural).

/**
 * @constructor
 */
function AutocompleteDirectionsHandler(map) {
  this.map = map;
  this.originPlaceId = null;
  this.destinationPlaceId = null;
  this.travelMode = 'DRIVING';
  this.directionsService = new google.maps.DirectionsService();
  this.directionsRenderer = new google.maps.DirectionsRenderer();
  this.directionsRenderer.setMap(map);

  var originInput = document.getElementById('orign');
  var destinationInput = document.getElementById('destn');

  var originAutocomplete = new google.maps.places.SearchBox(originInput);

  var destinationAutocomplete =
    new google.maps.places.SearchBox(destinationInput);

  this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
  this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');

}


AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function(
  autocomplete, mode) {
  var me = this;
  autocomplete.bindTo('bounds', this.map);

  autocomplete.addListener('places_changed', function() {
    var places = autocomplete.getPlaces();
    var place = places[0];

    if (!place.place_id) {
      window.alert('Please select an option from the dropdown list.');
      return;
    }
    if (mode === 'ORIG') {
      me.originPlaceId = place.place_id;
    } else {
      me.destinationPlaceId = place.place_id;
    }
    me.route();
  });
};

Add a function to calculate the length of the returned route (from the question: Google Maps API: Total distance with waypoints):

function computeTotalDistance(result) {
  var totalDist = 0;
  var totalTime = 0;
  var myroute = result.routes[0];
  for (i = 0; i < myroute.legs.length; i++) {
    totalDist += myroute.legs[i].distance.value;
    totalTime += myroute.legs[i].duration.value;
  }
  totalDist = totalDist / 1000.
  document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}

proof of concept fiddle

screenshot of resulting map

code snippet:

// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script
// src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">

function initMap() {
  var map = new google.maps.Map(document.getElementById('map-canvas'), {
    center: {
      lat: 19.4978,
      lng: -99.1269
    },
    zoom: 15
  });

  var marker = new google.maps.Marker({
    map: map,
    draggable: false
  });


  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
      map.setCenter(initialLocation);
      /*marker.setPosition(initialLocation);         */
    });
  }

  new AutocompleteDirectionsHandler(map);
}

/**
 * @constructor
 */
function AutocompleteDirectionsHandler(map) {
  this.map = map;
  this.originPlaceId = null;
  this.destinationPlaceId = null;
  this.travelMode = 'DRIVING';
  this.directionsService = new google.maps.DirectionsService();
  this.directionsRenderer = new google.maps.DirectionsRenderer();
  this.directionsRenderer.setMap(map);

  var originInput = document.getElementById('orign');
  var destinationInput = document.getElementById('destn');

  var originAutocomplete = new google.maps.places.SearchBox(originInput);

  var destinationAutocomplete =
    new google.maps.places.SearchBox(destinationInput);

  this.setupPlaceChangedListener(originAutocomplete, 'ORIG');
  this.setupPlaceChangedListener(destinationAutocomplete, 'DEST');

}


AutocompleteDirectionsHandler.prototype.setupPlaceChangedListener = function(
  autocomplete, mode) {
  var me = this;
  autocomplete.bindTo('bounds', this.map);

  autocomplete.addListener('places_changed', function() {
    var places = autocomplete.getPlaces();
    var place = places[0];

    if (!place.place_id) {
      window.alert('Please select an option from the dropdown list.');
      return;
    }
    if (mode === 'ORIG') {
      me.originPlaceId = place.place_id;
    } else {
      me.destinationPlaceId = place.place_id;
    }
    me.route();
  });
};

AutocompleteDirectionsHandler.prototype.route = function() {
  if (!this.originPlaceId || !this.destinationPlaceId) {
    return;
  }
  var me = this;

  this.directionsService.route({
      origin: {
        'placeId': this.originPlaceId
      },
      destination: {
        'placeId': this.destinationPlaceId
      },
      travelMode: this.travelMode
    },
    function(response, status) {
      if (status === 'OK') {
        me.directionsRenderer.setDirections(response);
        computeTotalDistance(response);
      } else {
        window.alert('Directions request failed due to ' + status);
      }
    });
};
// from Google Maps API: Total distance with waypoints
// https://stackoverflow.com/questions/12802202/google-maps-api-total-distance-with-waypoints
function computeTotalDistance(result) {
  var totalDist = 0;
  var totalTime = 0;
  var myroute = result.routes[0];
  for (i = 0; i < myroute.legs.length; i++) {
    totalDist += myroute.legs[i].distance.value;
    totalTime += myroute.legs[i].duration.value;
  }
  totalDist = totalDist / 1000.
  document.getElementById("total").innerHTML = "total distance is: " + totalDist + " km<br>total time is: " + (totalTime / 60).toFixed(2) + " minutes";
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

#map-canvas {
  height: 80%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div style="background-color: #FFC012; height:100%; width:100%;">
  <input type="text" id="orign" placeholder="origin" value="Lindavista Vallejo III Secc">
  <input type="text" id="destn" placeholder="destination" value="Lienzo Charro de La Villa">
  <div id="total"></div>
  <br>
  <div id="map-canvas"></div>
</div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap" async defer></script>
geocodezip
  • 158,664
  • 13
  • 220
  • 245