Search code examples
javascriptgoogle-maps-api-3polylinesubmit-button

Google maps api customized polyline


I want to create two input boxes which will autocomplete locations and then a submit button which when clicked will create a polyline between the two input locations on the map. My code does the autocompletion perfectly but is not able to mark the line between the sites on clicking the submit button. Please help.Help me in debugging.

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>

<script>
function initialize() {
   var mapOptions = {
center: new google.maps.LatLng(-33.8688, 151.2195),
zoom: 13
};
     var map = new google.maps.Map(document.getElementById('map-canvas'),


 mapOptions);

  var input = /** @type {HTMLInputElement} */(
      document.getElementById('pac-input'));

  var input1=(document.getElementById('pac-input1'));

  //var types = document.getElementById('type-selector');
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input1);

  var autocomplete = new google.maps.places.Autocomplete(input);
  autocomplete.bindTo('bounds', map);

  var autocomplete = new google.maps.places.Autocomplete(input1);
  autocomplete.bindTo('bounds', map);

  var infowindow = new google.maps.InfoWindow();
  var marker = new google.maps.Marker({
    map: map,
    anchorPoint: new google.maps.Point(0, -29)
  });

   var polyOptions = {
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 3
  };
  poly = new google.maps.Polyline(polyOptions);
  poly.setMap(map);
google.maps.event.addListener(submit, 'click', addLatLng);


/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * @param {google.maps.MouseEvent} event
 */
function addLatLng(event) {

  var path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear.
  path.push(event.latLng);

  // Add a new marker at the new plotted point on the polyline.
  var marker = new google.maps.Marker({
    position: event.latLng,
    title: '#' + path.getLength(),
    map: map
  });
}


  google.maps.event.addListener(autocomplete, 'place_changed', function() {
    infowindow.close();
    marker.setVisible(false);
    var place = autocomplete.getPlace();
    if (!place.geometry) {
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);  // Why 17? Because it looks good.
    }
    marker.setIcon(/** @type {google.maps.Icon} */({
      url: place.icon,
      size: new google.maps.Size(71, 71),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(17, 34),
      scaledSize: new google.maps.Size(35, 35)
    }));
    marker.setPosition(place.geometry.location);
    marker.setVisible(true);

    var address = '';
    if (place.address_components) {
      address = [
        (place.address_components[0] && place.address_components[0].short_name || ''),
        (place.address_components[1] && place.address_components[1].short_name || ''),
        (place.address_components[2] && place.address_components[2].short_name || '')
      ].join(' ');
    }

    infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
    infowindow.open(map, marker);
  });


 }

google.maps.event.addDomListener(window, 'load', initialize);

</script> 

The body of my html file is as follows:

<input id="pac-input" class="controls" type="text" placeholder="Enter a location">
<input id="pac-input1" class="controls" type="text" placeholder="Enter another location">

<div id="type-selector" class="controls">
  <input  type="submit" name="submit" value="SUBMIT">
</div>
<div id="map-canvas"></div>

Solution

  • I get a javascript error with your code: Uncaught ReferenceError: submit is not defined

    google.maps.event.addListener(submit, 'click', addLatLng);
    

    should be:

    google.maps.event.addListener(document.getElementById('submit'), 'click', addLatLng);
    

    (but it turns out you don't need that)

    Once I fix that, I only get one marker. because you only have one autocomplete:

    var autocomplete = new google.maps.places.Autocomplete(input);
    autocomplete.bindTo('bounds', map);
    
    var autocomplete = new google.maps.places.Autocomplete(input1);
    autocomplete.bindTo('bounds', map);
    

    should be:

    var autocomplete = new google.maps.places.Autocomplete(input);
    autocomplete.bindTo('bounds', map);
    
    var autocomplete1 = new google.maps.places.Autocomplete(input1);
    autocomplete.bindTo('bounds', map);
    

    then you need a 'place_changed' listener for autocomplete1.

    If you want those positions to be the ends of your polyline, you have to add them to the path:

    poly.getPath().setAt(0, marker.getPosition());
    

    working fiddle

    working code snippet:

    function initialize() {
        var mapOptions = {
            center: new google.maps.LatLng(-33.8688, 151.2195),
            zoom: 13
        };
        var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
        var input = /** @type {HTMLInputElement} */
        (
        document.getElementById('pac-input'));
    
        var input1 = (document.getElementById('pac-input1'));
    
        //var types = document.getElementById('type-selector');
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
        map.controls[google.maps.ControlPosition.TOP_LEFT].push(input1);
    
        var autocomplete = new google.maps.places.Autocomplete(input);
        autocomplete.bindTo('bounds', map);
    
        var autocomplete1 = new google.maps.places.Autocomplete(input1);
        autocomplete.bindTo('bounds', map);
    
        var infowindow = new google.maps.InfoWindow();
        var marker = new google.maps.Marker({
            map: map,
            anchorPoint: new google.maps.Point(0, -29)
        });
    
        var marker1 = new google.maps.Marker({
            map: map,
            anchorPoint: new google.maps.Point(0, -29)
        });
        var polyOptions = {
            strokeColor: '#000000',
            strokeOpacity: 1.0,
            strokeWeight: 3
        };
        poly = new google.maps.Polyline(polyOptions);
        poly.setMap(map);
    
        google.maps.event.addListener(autocomplete, 'place_changed', function () {
            infowindow.close();
            marker.setVisible(false);
            var place = autocomplete.getPlace();
            if (!place.geometry) {
                return;
            }
    
            // If the place has a geometry, then present it on a map.
            if (place.geometry.viewport) {
                map.fitBounds(place.geometry.viewport);
            } else {
                map.setCenter(place.geometry.location);
                map.setZoom(17); // Why 17? Because it looks good.
            }
            marker.setIcon( /** @type {google.maps.Icon} */ ({
                url: place.icon,
                size: new google.maps.Size(71, 71),
                origin: new google.maps.Point(0, 0),
                anchor: new google.maps.Point(17, 34),
                scaledSize: new google.maps.Size(35, 35)
            }));
            marker.setPosition(place.geometry.location);
            marker.setVisible(true);
            poly.getPath().setAt(0, marker.getPosition());
    
            var address = '';
            if (place.address_components) {
                address = [
                (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '')].join(' ');
            }
    
            infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
            infowindow.open(map, marker);
        });
    
        google.maps.event.addListener(autocomplete1, 'place_changed', function () {
            infowindow.close();
            marker1.setVisible(false);
            var place = autocomplete1.getPlace();
            if (!place.geometry) {
                return;
            }
    
            // If the place has a geometry, then present it on a map.
            if (place.geometry.viewport) {
                map.fitBounds(place.geometry.viewport);
            } else {
                map.setCenter(place.geometry.location);
                map.setZoom(17); // Why 17? Because it looks good.
            }
            marker1.setIcon( /** @type {google.maps.Icon} */ ({
                url: place.icon,
                size: new google.maps.Size(71, 71),
                origin: new google.maps.Point(0, 0),
                anchor: new google.maps.Point(17, 34),
                scaledSize: new google.maps.Size(35, 35)
            }));
            marker1.setPosition(place.geometry.location);
            marker1.setVisible(true);
            poly.getPath().setAt(1, marker1.getPosition());
    
            var address = '';
            if (place.address_components) {
                address = [
                (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '')].join(' ');
            }
    
            infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
            infowindow.open(map, marker1);
        });
    }
    
    google.maps.event.addDomListener(window, 'load', initialize);
    html, body, #map-canvas {
        width: 100%;
        height: 100%;
    }
    <script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
    <input id="pac-input" class="controls" type="text" placeholder="Enter a location" />
    <input id="pac-input1" class="controls" type="text" placeholder="Enter another location" />
    <div id="type-selector" class="controls">
        <input type="submit" name="submit" id="submit" value="SUBMIT" />
    </div>
    <div id="map-canvas"></div>