0

Case:

I am displaying a Google Map using the V3 API and let the users type some origin and destination in input fields, which use the autocomplete functionality.

If the user types an origin, a marker is created and placed in the map. The map is centered and zommed to this marker.

If the user also types a destination, a new marker is placed, but the map is adjusted to show both markers using the fitBounds() method. Additionally, a polyline is drawn to "join" both markers.

If the user types a new origin or destination, the markers and the polyline are updated consequently.

It doesn't matter if the user starts typing a destination or an origin, as the code works in "both ways".

Problem:

My code seems to work properly if I type countries, regions or cities, but it fails if I type something else. Something as places (buildings, shops, attractions...), streets... The markers are correctly placed, but the map is not zoomed accordingly and the polyline is not drawn.

The console shows no errors.

If I update origin or destination with a city, region or country, the map works as intended, and the polyline appears correctly, even when the other element is a street or place.

Code:

 $(document).ready(function () {


   // Create an array of styles.
   var styles = [{
     "featureType": "administrative",
     "elementType": "all",
     "stylers": [{
       "visibility": "on"
     }, {
       "lightness": 33
     }]
   }, {
     "featureType": "landscape",
     "elementType": "all",
     "stylers": [{
       "color": "#f2e5d4"
     }]
   }, {
     "featureType": "poi.park",
     "elementType": "geometry",
     "stylers": [{
       "color": "#c5dac6"
     }]
   }, {
     "featureType": "poi.park",
     "elementType": "labels",
     "stylers": [{
       "visibility": "on"
     }, {
       "lightness": 20
     }]
   }, {
     "featureType": "road",
     "elementType": "all",
     "stylers": [{
       "lightness": 20
     }]
   }, {
     "featureType": "road.highway",
     "elementType": "geometry",
     "stylers": [{
       "color": "#c5c6c6"
     }]
   }, {
     "featureType": "road.arterial",
     "elementType": "geometry",
     "stylers": [{
       "color": "#e4d7c6"
     }]
   }, {
     "featureType": "road.local",
     "elementType": "geometry",
     "stylers": [{
       "color": "#fbfaf7"
     }]
   }, {
     "featureType": "water",
     "elementType": "all",
     "stylers": [{
       "visibility": "on"
     }, {
       "color": "#acbcc9"
     }]
   }];

   // Create a new StyledMapType object, passing it the array of styles,
   // as well as the name to be displayed on the map type control.
   var styledMap = new google.maps.StyledMapType(styles, {
     name: "Styled Map"
   });

   var lat = 40.8688,
     lng = 17.2195,
     latlng = new google.maps.LatLng(lat, lng)

   var mapOptions = {
       center: new google.maps.LatLng(lat, lng),
       zoom: 3,
       mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style'],
       disableDefaultUI: true
     },
     map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions)

   //Associate the styled map with the MapTypeId and set it to display.
   map.mapTypes.set('map_style', styledMap);
   map.setMapTypeId('map_style');

   //First autocomplete
   var input = /** @type {!HTMLInputElement} */ (
     document.getElementById('searchTextField1'));


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

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

   autocomplete.addListener('place_changed', function () {
     marker.setVisible(false);
     place = autocomplete.getPlace();
     if (!place.geometry) {
       window.alert("Autocomplete's returned place contains no geometry");
       return;
     }

     // If the place has a geometry, then present it on a map.
     if (typeof place2 !== "undefined" && place.geometry.viewport) {
       var bounds = new google.maps.LatLngBounds();
       bounds.extend(place.geometry.location);
       bounds.extend(place2.geometry.location);
       map.fitBounds(bounds);
       pano_lat = place.geometry.location.lat();
       pano_lng = place.geometry.location.lng();
       getPanoramio(pano_lat, pano_lng);
       route();
     } else {
       map.setCenter(place.geometry.location);
       map.setZoom(17); // Why 17? Because it looks good.
       pano_lat = place.geometry.location.lat();
       pano_lng = place.geometry.location.lng();
       getPanoramio(pano_lat, pano_lng);
     }
     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);

   });


   //Second autocomplete
   var input2 = /** @type {!HTMLInputElement} */ (
     document.getElementById('searchTextField2'));


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

   var marker2 = new google.maps.Marker({
     map: map,
     anchorPoint2: new google.maps.Point(0, -29)
   });

   autocomplete2.addListener('place_changed', function () {
     marker2.setVisible(false);
     place2 = autocomplete2.getPlace();
     if (!place2.geometry) {
       window.alert("Autocomplete's returned place contains no geometry");
       return;
     }

     // If the place has a geometry, then present it on a map.
     if (typeof place !== "undefined" && place2.geometry.viewport) {
       var bounds = new google.maps.LatLngBounds();
       bounds.extend(place2.geometry.location);
       bounds.extend(place.geometry.location);
       map.fitBounds(bounds);
       pano_lat = place2.geometry.location.lat();
       pano_lng = place2.geometry.location.lng();
       getPanoramio(pano_lat, pano_lng);
       route();
     } else {
       map.setCenter(place2.geometry.location);
       map.setZoom(17); // Why 17? Because it looks good.
       pano_lat = place2.geometry.location.lat();
       pano_lng = place2.geometry.location.lng();
       getPanoramio(pano_lat, pano_lng);
     }
     marker2.setIcon( /** @type {google.maps.Icon} */ ({
       url: place2.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)
     }));
     marker2.setPosition(place2.geometry.location);
     marker2.setVisible(true);


   });

   function route() {
     var flightPlanCoordinates = [{
       lat: place.geometry.location.lat(),
       lng: place.geometry.location.lng()
     }, {
       lat: place2.geometry.location.lat(),
       lng: place2.geometry.location.lng()
     }];
     if (typeof flightPath !== "undefined") {
       flightPath.setPath(flightPlanCoordinates);
     } else {
       var lineSymbol = {
         path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
       };
       flightPath = new google.maps.Polyline({
         path: flightPlanCoordinates,
         strokeColor: "#FF0000",
         strokeOpacity: 1.0,
         strokeWeight: 2,
         icons: [{
           icon: lineSymbol,
           offset: '25%'
         }, {
           icon: lineSymbol,
           offset: '50%'
         }, {
           icon: lineSymbol,
           offset: '75%'
         }],
       });
       flightPath.setMap(map);
     }
   }

   function getPanoramio(a, b) {
     console.log(a);
     console.log(b);
     $.ajax({
       url: 'http://www.panoramio.com/map/get_panoramas.php?set=public&from=0&to=20&minx=' + (b - 0.005) + '&miny=' + (a - 0.005) + '&maxx=' + (b + 0.005) + '&maxy=' + (a + 0.005) + '&size=original&mapfilter=true',
       dataType: 'jsonp',
       success: function (dataWeGotViaJsonp) {
         imgFondo = dataWeGotViaJsonp.photos[0].photo_file_url;
         $("#fondo_form").css("background-image", "url(" + imgFondo + ")");
       }
     });
   }

 });

Demo:

You can reproduce this rare behaviour in this jsfiddle

Sample input data that works:

  • Munich
  • Bavaria
  • Germany
  • Manhattan
  • New York

Sample input data that doesn't work:

  • Lehel, Munich, Germany
  • 5th Avenue, New York City...
  • Taj Mahal, Agra...
  • Heathrow Airport
  • Zara Home, Regent Street...
agustin
  • 1,311
  • 20
  • 42
  • Please provide sample input data that will reproduce your issue. – geocodezip Dec 03 '15 at 02:04
  • Added sample data under Demo for working and not working examples – agustin Dec 03 '15 at 02:12
  • Seems like your issue is that some of the places responses don't have `geometry` properties. You have code that detects that and bails out. Weird thing is it seems to work sometimes and not work others, can't tell if that is something in your code or not (your code has strange dependencies on the other place and the viewport) . It might be worth creating a [Minimal, Complete, Tested and Readable example](http://stackoverflow.com/help/mcve) that exhibits the issue to remove the complications in your code from effecting the output and trying the various releases (experimental/release/frozen). – geocodezip Dec 03 '15 at 02:50
  • Sometimes you need a small tip! I was trying to make a minimal, complete, readable example, when I realized, that the problem was in my code. `if (typeof place2 !== "undefined" && place.geometry.viewport)` is doing the job correctly, but when you type more detailed places (as streets) the `place.geometry.viewport` condition is not satisfied, so the code jumps to the else statement. The solution was simply adding an extra `if(typeof place2 !=="undefined")` statement inside this else. What would you recommend to follow with this question? Is clearly a problem with my code. Shoud I answer myself? – agustin Dec 03 '15 at 12:09
  • It should be closed as off-topic because: Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – geocodezip Dec 03 '15 at 13:56
  • Thanks. Voted for closing – agustin Dec 03 '15 at 14:04
  • Might be useful for historical reasons to answer it with what you discovered and posted in the comments. – geocodezip Dec 03 '15 at 14:07

0 Answers0