Google Maps API-maps.setCenter似乎不在用户位置的中心 [英] Google Maps API - maps.setCenter doesn't seem to be centering to users position

查看:75
本文介绍了Google Maps API-maps.setCenter似乎不在用户位置的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用Google Maps API,有一件事特别困扰我.

I've been using the Google Maps API, and one thing is particularly bugging me.

我在页面加载时设置了原始地图,然后,当用户单击登录"按钮并共享其位置时,会在屏幕上显示一个商店"数组,其中包含用户位置和商店之间计算出的距离标记上方的信息窗口.

I set the original Map on page load, and then once the user clicks a 'sign in' button and shares their location, an array of 'shops' with the distance calculated between the users position and the shops is displayed in an info window above the marker.

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

The problem I'm having - in Firefox - is that the array of shops loads, and the map centers in the middle of the shop positions instead of the map centering on the users location.

此处的某些变量仅在此刻保留虚拟内容.

Some of the variables here are holding dummy content at the moment only.

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

When the last function (addDabblerArrayToMap) runs, it checks the 'centerPos' - the variable which holds the users location, and then does either one action or another: 1. If centerPos = null, the markers are added to the map, and the default position is dropped on to the map, without any distance calculation occurring. 2. If centerPos holds a lat & lng, then the distance between each shop and the user is calculated and appended to an infoWindow which is displayed above the relative shop marker, so a user can see how far away each shop is from their position.

  • 运行时,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);
    }
}

推荐答案

问题在于您执行工作的顺序.用户位置的map.setCenteraddMarkerWithTimeout调用超时之前运行.将这些标记添加到地图后,它们的信息窗口将打开,这将使地图居中以显示上一次打开的信息窗口.

The problem is the order you are doing things. The map.setCenter to the user's position runs before the time outs fire on the addMarkerWithTimeout calls. When those markers are added to the map, their infowindows open, which centers the map to show the last infowindow opened.

一个解决此问题的方法是在信息窗口中设置disableAutoPan: true.

one option to fix this is to set disableAutoPan: true on the infowindows.

概念证明小提琴

代码段:

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);

html,
body {
  height: 100%;
}
#map {
  height: 90%;
}

<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map"></div>
<button onClick="runAllChainEvents();">Sign in</button>

这篇关于Google Maps API-maps.setCenter似乎不在用户位置的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆