Google Maps API - maps.setCenter似乎并未以用户位置

时间:2016-09-12 12:25:00

标签: javascript google-maps google-maps-api-3

我一直在使用谷歌地图API,有一件事特别困扰我。

我在页面加载时设置了原始地图,然后一旦用户点击“登录”按钮并分享他们的位置,就会在一个“商店”数组中显示用户位置和商店之间的距离。标记上方的信息窗口。

我在Firefox中遇到的问题是,商店阵列加载,地图位于商店中间位置,而不是以用户位置为中心的地图。

此处的一些变量仅包含虚拟内容。

当最后一个函数(addDabblerArrayToMap)运行时,它会检查'centerPos' - 保存用户位置的变量,然后执行一个或另一个操作: 1.如果centerPos = null,则将标记添加到地图中,并将默认位置放到地图上,而不进行任何距离计算。 2.如果centerPos持有lat&然后,计算每个商店和用户之间的距离并将其附加到显示在相关商店标记上方的infoWindow,以便用户可以看到每个商店离他们的位置有多远。

  • 运行此选项时,map.setCenter(centerPos)不会将地图置于用户位置的中心位置。它将地图设置在商店阵列的中间。我可以进入浏览器控制台并键入“map.setCenter(centerPos)” - 然后它将地图居中到用户位置。

以下完整代码:

HTML:

<div id="map"></div>
<button onClick="runAllChainEvents();">Sign in</button>

CSS:

#map {
   height: 100%;
}

JS:

var neighborhoods = [
    {lat: -36.862338, lng: 174.7425013},
    {lat: -36.867204, lng: 174.7692113},
    {lat: -36.848362, lng: 174.7426733},
    {lat: -36.845028, lng: 174.7748043},
    {lat: -36.862644, lng: 174.7340973},
    {lat: -36.862775, lng: 174.7836023}
];
var markers =[];
var map;
var dabblers = "../favicon-32x32.png";
var yourLocation = "../dabble-icon.png";
var myLocationIconArray = [];
var hasHappened = false;
var infoWindowContentString = '';
var dabblerInfoWindow = null;
var addInfowindow;
var distanceArray = [];
var defaultPos = {lat: -36.8527785, lng: 174.7617562};
var centerPos;

var dabblersArray = [
    {lat: -36.862338, lng: 174.7425013, type: 'sweet'},
    {lat: -36.867204, lng: 174.7692113, type: 'sweet'},
    {lat: -36.848362, lng: 174.7426733, type: 'sweet'},
    {lat: -36.845028, lng: 174.7748043, type: 'savoury'},
    {lat: -36.862644, lng: 174.7340973, type: 'savoury'},
    {lat: -36.862775, lng: 174.7836023, type: 'savoury'}
];

/* Initializes map with custom styles, centers location, 
   and defines Map UI */
function initMap() {
    var customMapType = new google.maps.StyledMapType([
        {
          stylers: [
            {hue: '#8c8c8c'},
            {visibility: 'simplified'}
          ]
        },
        {
          elementType: 'labels',
          stylers: [{visibility: 'off'}]
        },
        {
          elementType: 'landscape',
          stylers: [{color: '#e6e6e6'}]
        },
        {
          featureType: 'road',
          stylers: [{color: '#ffffff'}]
        },
        {
          featureType: 'road.highway.controlled_access',
          stylers: [{color: '#cccccc'}]
        },
        {
          featureType: 'road.arterial',
          stylers: [{color: '#cccccc'}]
        },
        {
          featureType: 'water',
          stylers: [
            {color: '#dce6e6'},
            {"lightness": -10},
            {"saturation": -30}
          ]
        },
        {
          featureType: 'poi',
          stylers: [{visibility: 'off'}]
        },
        {
          featureType: 'transit.line',
          stylers: [{visibility: 'off'}]
        }
    ], { name: 'Custom Style'
    });   
    var customMapTypeId = 'custom_style';
    map = new google.maps.Map(document.getElementById('map'), {
          center: { lat: -36.8527785, lng: 174.7617562}, // Auckland City coords
          zoom: 15,
          disableDefaultUI: true,
          zoomControl: false,
          mapTypeControl: false,
          scaleControl: false,
          fullscreenControl: false,
          streetViewControl: false,
          mapTypeControlOptions: {
            mapTypeIds: [google.maps.MapTypeId.ROADMAP, customMapTypeId]
          }
    });
    map.mapTypes.set(customMapTypeId, customMapType);
    map.setMapTypeId(customMapTypeId);
    map.setOptions({draggable: false, zoomControl: false,
    zoomControlOptions: {
              position: google.maps.ControlPosition.BOTTOM_CENTER
          },
    scrollwheel: false, disableDoubleClickZoom: true});
    drop();
}

/* Takes positions in neighborhoodsArray and runs each through 
   the addMarkerWithTimeout function */
function drop() {
  var delay = 800;
    for (var i = 0; i < neighborhoods.length; i++) {
      addMarkerWithTimeout(neighborhoods[i], i*200 + delay);
    }
}

/* Takes position (lat / long) and timeout parameters and converts 
   into Google Map Markers. Then adds to Google Map. */
function addMarkerWithTimeout(position, timeout) {
    window.setTimeout(function() {
      markers.push(new google.maps.Marker({
        position: position,
        map: map,
        animation: google.maps.Animation.DROP,
        icon: dabblers,
        draggable: false,
        clickable: false
      }));
    }, timeout);
}

/*  Clears original markers from map and sets relative arrays to [] */
function deleteMarkers() {
    for (var x = 0; x < markers.length; x++) {
      markers[x].setMap(null);
    }
    markers = [];
    neighborhoods = [];
}

/* Adds your location & infoWindow to map after signIn */   
function addMarker(location, addInfowindow) {
    var marker = new google.maps.Marker({
        position: location,
        map: map,
        animation: google.maps.Animation.DROP,
        icon: yourLocation,
        draggable: false,
        clickable: true
    });
    if (addInfowindow == null) {
        var myLocationInfowindow = new google.maps.InfoWindow({
          content: "Your location"
        });
        myLocationInfowindow.open(map, marker);
        myLocationIconArray.push(marker);
    } else {
        var myLocationInfowindow = new google.maps.InfoWindow({
          content: infoWindowContentString
        });
        myLocationInfowindow.open(map, marker);
        myLocationIconArray.push(marker);
    }
}

/* Checks if Users browser / device is capable of Geolocation. If it is, gets current position */
function getUserLocation(onComplete) {  
    map.setOptions({draggable: true, zoomControl: true, scrollwheel: true, disableDoubleClickZoom: false});

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            centerPos = {
                lat: position.coords.latitude,
                lng: position.coords.longitude
            };
            map.setCenter(centerPos);
            addMarker(centerPos);
            onComplete();
        }, function() {
            handleLocationError(true, addInfowindow, map.getCenter());
        });
    } else {
        //Browser doesn't support Geolocation
        handleLocationError(false, addInfowindow, map.getCenter());
    }
}

/* Removes elements, and adds Dabblers to map */
function runAllChainEvents() {
    getUserLocation(addDabblerArrayToMap);
}

/* Handles error if Users browser / device is not capable of Geolocation
   lookup functionality. Places their location at centre of Auckland. */    
function handleLocationError(browserHasGeolocation, addInfowindow, defaultPos) {
    if (browserHasGeolocation) {
        infoWindowContentString = "Sorry, we can't get your location."; 
    } else {
        infoWindowContentString = "Your current browser does not support Geolocation.";
    }
    addInfowindow = new google.maps.InfoWindow({
          content: infoWindowContentString
        });
    map.setCenter(defaultPos);
    addMarker(defaultPos, addInfowindow);
    addDabblerArrayToMap(null);
}

/* Takes positions in dabblersArray and runs each through 
   the addMarkerWithTimeout function. Then calculates the 
   distance between user and dabblers.   */
function addDabblerArrayToMap(position1) {
    var distance;
    var dabblerLocation;
    deleteMarkers();
    position1 = centerPos;

    if (position1 == null) {
        for (var z = 0; z < dabblersArray.length; z++) {
            markers.push(new google.maps.Marker({
            position: { lat: dabblersArray[z].lat, lng: dabblersArray[z].lng},
            map: map,
            icon: dabblers,
            draggable: false,
            clickable: true,
            id: dabblersArray[z].type
            }));
        }
    } else {
        var usersPosition = new google.maps.LatLng(centerPos.lat, centerPos.lng);

        for (var y = 0; y < dabblersArray.length; y++) {    
            dabblerLocation = new google.maps.LatLng(dabblersArray[y].lat, dabblersArray[y].lng);

            distance = google.maps.geometry.spherical.computeDistanceBetween(usersPosition, dabblerLocation);
            distance = parseFloat(distance / 1000).toFixed(2);
            distanceArray.push(distance);

            dabblerInfoWindow = new google.maps.InfoWindow({
                content: distance + "km"
            });

            markers.push(new google.maps.Marker({
            position: { lat: dabblersArray[y].lat, lng: dabblersArray[y].lng },
                map: map,
                icon: dabblers,
                draggable: false,
                clickable: true,
                id: dabblersArray[y].type
            }));
            dabblerInfoWindow.open(map, markers[y]);
        }
    // I shouldn't need to add this here, but have tried to set Center
       position manually again here to no avail also.
    map.setCenter(centerPos);
    }
}

1 个答案:

答案 0 :(得分:2)

问题在于你正在做的事情。 map.setCenter到用户的位置会在addMarkerWithTimeout来电超时之前运行。当这些标记被添加到地图中时,它们的信息窗口会打开,这会使地图居中,以显示最后打开的信息窗口。

解决此问题的一个选项是在infowindows上设置disableAutoPan: true

proof of concept fiddle

代码段

&#13;
&#13;
var neighborhoods = [{
  lat: -36.862338,
  lng: 174.7425013
}, {
  lat: -36.867204,
  lng: 174.7692113
}, {
  lat: -36.848362,
  lng: 174.7426733
}, {
  lat: -36.845028,
  lng: 174.7748043
}, {
  lat: -36.862644,
  lng: 174.7340973
}, {
  lat: -36.862775,
  lng: 174.7836023
}];
var markers = [];
var map;
var dabblers = "https://maps.google.com/mapfiles/ms/micons/blue.png";
var yourLocation = "https://maps.google.com/mapfiles/ms/micons/red.png";
var myLocationIconArray = [];
var hasHappened = false;
var infoWindowContentString = '';
var dabblerInfoWindow = null;
var addInfowindow;
var distanceArray = [];
var defaultPos = {
  lat: -36.8527785,
  lng: 174.7617562
};
var centerPos;

var dabblersArray = [{
  lat: -36.862338,
  lng: 174.7425013,
  type: 'sweet'
}, {
  lat: -36.867204,
  lng: 174.7692113,
  type: 'sweet'
}, {
  lat: -36.848362,
  lng: 174.7426733,
  type: 'sweet'
}, {
  lat: -36.845028,
  lng: 174.7748043,
  type: 'savoury'
}, {
  lat: -36.862644,
  lng: 174.7340973,
  type: 'savoury'
}, {
  lat: -36.862775,
  lng: 174.7836023,
  type: 'savoury'
}];

/* Initializes map with custom styles, centers location, 
   and defines Map UI */
function initMap() {
  var customMapType = new google.maps.StyledMapType([{
    stylers: [{
      hue: '#8c8c8c'
    }, {
      visibility: 'simplified'
    }]
  }, {
    elementType: 'labels',
    stylers: [{
      visibility: 'off'
    }]
  }, {
    elementType: 'landscape',
    stylers: [{
      color: '#e6e6e6'
    }]
  }, {
    featureType: 'road',
    stylers: [{
      color: '#ffffff'
    }]
  }, {
    featureType: 'road.highway.controlled_access',
    stylers: [{
      color: '#cccccc'
    }]
  }, {
    featureType: 'road.arterial',
    stylers: [{
      color: '#cccccc'
    }]
  }, {
    featureType: 'water',
    stylers: [{
      color: '#dce6e6'
    }, {
      "lightness": -10
    }, {
      "saturation": -30
    }]
  }, {
    featureType: 'poi',
    stylers: [{
      visibility: 'off'
    }]
  }, {
    featureType: 'transit.line',
    stylers: [{
      visibility: 'off'
    }]
  }], {
    name: 'Custom Style'
  });
  var customMapTypeId = 'custom_style';
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: -36.8527785,
      lng: 174.7617562
    }, // Auckland City coords
    zoom: 15,
    disableDefaultUI: true,
    zoomControl: false,
    mapTypeControl: false,
    scaleControl: false,
    fullscreenControl: false,
    streetViewControl: false,
    mapTypeControlOptions: {
      mapTypeIds: [google.maps.MapTypeId.ROADMAP, customMapTypeId]
    }
  });
  map.mapTypes.set(customMapTypeId, customMapType);
  map.setMapTypeId(customMapTypeId);
  map.setOptions({
    draggable: false,
    zoomControl: false,
    zoomControlOptions: {
      position: google.maps.ControlPosition.BOTTOM_CENTER
    },
    scrollwheel: false,
    disableDoubleClickZoom: true
  });
  drop();
}

/* Takes positions in neighborhoodsArray and runs each through 
   the addMarkerWithTimeout function */
function drop() {
  var delay = 800;
  for (var i = 0; i < neighborhoods.length; i++) {
    addMarkerWithTimeout(neighborhoods[i], i * 200 + delay);
  }
}

/* Takes position (lat / long) and timeout parameters and converts 
   into Google Map Markers. Then adds to Google Map. */
function addMarkerWithTimeout(position, timeout) {
  window.setTimeout(function() {
    markers.push(new google.maps.Marker({
      position: position,
      map: map,
      animation: google.maps.Animation.DROP,
      icon: dabblers,
      draggable: false,
      clickable: false
    }));
  }, timeout);
}

/*  Clears original markers from map and sets relative arrays to [] */
function deleteMarkers() {
  for (var x = 0; x < markers.length; x++) {
    markers[x].setMap(null);
  }
  markers = [];
  neighborhoods = [];
}

/* Adds your location & infoWindow to map after signIn */
function addMarker(location, addInfowindow) {
  var marker = new google.maps.Marker({
    position: location,
    map: map,
    animation: google.maps.Animation.DROP,
    icon: yourLocation,
    draggable: false,
    clickable: true
  });
  if (addInfowindow == null) {
    var myLocationInfowindow = new google.maps.InfoWindow({
      content: "Your location",
      disableAutoPan: false
    });
    myLocationInfowindow.open(map, marker);
    myLocationIconArray.push(marker);
  } else {
    var myLocationInfowindow = new google.maps.InfoWindow({
      content: infoWindowContentString,
      disableAutoPan: true
    });
    myLocationInfowindow.open(map, marker);
    myLocationIconArray.push(marker);
  }
}

/* Checks if Users browser / device is capable of Geolocation. If it is, gets current position */
function getUserLocation(onComplete) {
  map.setOptions({
    draggable: true,
    zoomControl: true,
    scrollwheel: true,
    disableDoubleClickZoom: false
  });

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      centerPos = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      };
      map.setCenter(centerPos);
      addMarker(centerPos);
      onComplete();
    }, function() {
      handleLocationError(true, addInfowindow, map.getCenter());
    });
  } else {
    //Browser doesn't support Geolocation
    handleLocationError(false, addInfowindow, map.getCenter());
  }
}

/* Removes elements, and adds Dabblers to map */
function runAllChainEvents() {
  getUserLocation(addDabblerArrayToMap);
}

/* Handles error if Users browser / device is not capable of Geolocation
   lookup functionality. Places their location at centre of Auckland. */
function handleLocationError(browserHasGeolocation, addInfowindow, defaultPos) {
  if (browserHasGeolocation) {
    infoWindowContentString = "Sorry, we can't get your location.";
  } else {
    infoWindowContentString = "Your current browser does not support Geolocation.";
  }
  addInfowindow = new google.maps.InfoWindow({
    content: infoWindowContentString,
    disableAutoPan: true
  });
  map.setCenter(defaultPos);
  addMarker(defaultPos, addInfowindow);
  addDabblerArrayToMap(null);
}

/* Takes positions in dabblersArray and runs each through 
   the addMarkerWithTimeout function. Then calculates the 
   distance between user and dabblers.   */
function addDabblerArrayToMap(position1) {
  var distance;
  var dabblerLocation;
  deleteMarkers();
  position1 = centerPos;

  if (position1 == null) {
    for (var z = 0; z < dabblersArray.length; z++) {
      markers.push(new google.maps.Marker({
        position: {
          lat: dabblersArray[z].lat,
          lng: dabblersArray[z].lng
        },
        map: map,
        icon: dabblers,
        draggable: false,
        clickable: true,
        id: dabblersArray[z].type
      }));
    }
  } else {
    var usersPosition = new google.maps.LatLng(centerPos.lat, centerPos.lng);

    for (var y = 0; y < dabblersArray.length; y++) {
      dabblerLocation = new google.maps.LatLng(dabblersArray[y].lat, dabblersArray[y].lng);

      distance = google.maps.geometry.spherical.computeDistanceBetween(usersPosition, dabblerLocation);
      distance = parseFloat(distance / 1000).toFixed(2);
      distanceArray.push(distance);

      dabblerInfoWindow = new google.maps.InfoWindow({
        content: distance + "km",
        disableAutoPan: true
      });

      markers.push(new google.maps.Marker({
        position: {
          lat: dabblersArray[y].lat,
          lng: dabblersArray[y].lng
        },
        map: map,
        icon: dabblers,
        draggable: false,
        clickable: true,
        id: dabblersArray[y].type
      }));
      dabblerInfoWindow.open(map, markers[y]);
    }
    // I shouldn't need to add this here, but have tried to set Center
    //    position manually again here to no avail also.
    // setTimeout(function() {
    map.setCenter(centerPos)
      //}, 5000);
  }
}
google.maps.event.addDomListener(window, "load", initMap);
&#13;
html,
body {
  height: 100%;
}
#map {
  height: 90%;
}
&#13;
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map"></div>
<button onClick="runAllChainEvents();">Sign in</button>
&#13;
&#13;
&#13;