Google 地图 fitBounds() 将地图缩放到很远的地方,尽管边界很小

Google Maps fitBounds() zooms map very far out despite bounds being small

我正在使用 Google 的 Fusion Tables API 来在地图上显示县的轮廓,然后将其适合任何视口。 fitBounds() 到目前为止对以前的地图有效,但是当我添加 Fusion Tables Layer 时,一切都开始变得奇怪。尽管纬度范围约为 -87 到 -89,经度范围约为 42 到 43,但以下代码最终会缩小地图以查看整个北美:

function initMap() {
  const API_KEY = <my api key>;
  const MAP_KEY = <my map key>;

  const map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(42.9065288383437, -88.35016674999997)
  });

  const style = [
    {
      featureType: 'all',
      elementType: 'all',
      stylers: [
        { saturation: 44 }
      ]
    }
  ];

  const styledMapType = new google.maps.StyledMapType(style, {
    map: map,
    name: 'Styled Map'
  });

  map.mapTypes.set('map-style', styledMapType);
  map.setMapTypeId('map-style');

  const layer = new google.maps.FusionTablesLayer({
    query: {
      select: "col4",
      from: MAP_KEY
    },
    map: map,
    styleId: 8,
    templateId: 2
  });

  getTableCoordinates(
    MAP_KEY,
    API_KEY,
    function (rows) {
      if (rows.length !== 0) {
        const bounds = new google.maps.LatLngBounds(null);

        /*
            Real examples of pair:
            [ -87.8199, 42.621 ],
            [ -87.4934, 42.123 ],
            [ -87.815094, 42.558089 ],
            etc.

            There's about ~1000 of these, all extremely close in lat and lng.
        */
        rows.forEach(function (pair) {
          const boundary = new google.maps.LatLng(pair[0], pair[1]);

          bounds.extend(boundary);
        });

        setMapBounds(map, bounds, map.getCenter());

        google.maps.event.addDomListener(window, "resize", function() {
          google.maps.event.trigger(map, "resize");
          setMapBounds(map, bounds, map.getCenter());
        });
      }
    }
  )
}

function getTableCoordinates(mapKey, apiKey, callback) {
  const apiLink = "https://www.googleapis.com/fusiontables/v2/query?";
  const query = [
      "SELECT",
      "col4",
      "FROM",
      mapKey
    ]
    .join("+");

  $.ajax({
    url: apiLink + "sql=" + query + "&key=" + apiKey,
    dataType: "json"
  })
  .done(function (response) {
    callback(
      response
        .rows
        .map(function(row) {
          return row[0].geometry.coordinates[0];
        })
        .reduce(function(a, b) {
          return a.concat(b);
        })
    );
  })
  .fail(function () {
    callback([]);
  });
}

function setMapBounds(map, bounds, center) {
  map.fitBounds(bounds);

  if (center) {
    google.maps.event.addListenerOnce(map, "bounds_changed",
      (function (event) {
        // Reset center since fitBounds can change it
        map.setCenter(center);
      })
    );
  }
}

我知道 map() 调用看起来很奇怪,但它会返回我需要的所有有效坐标。数据很好,我已经看过边界的一角,但到目前为止它仍然缩小了。

几个问题:

  1. 看起来 pair[0], pair[1] 应该是 pair[1], pair[0](比如您的坐标是经度、纬度,而 google.maps.LatLng 需要纬度、经度)。
    纬度 -87 低于南极附近的可用图块。如果我翻转它们,我会得到密尔沃基附近的位置。 (与您的地图中心中心比较:新 google.maps.LatLng(42.9065288383437, -88.35016674999997))

  2. 如果 center 不是边界的中心,
  3. this map.setCenter(center); 会导致 setMapBounds 方法出现异常。

proof of concept fiddle

代码片段:

function initMap() {
  const map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(42.9065288383437, -88.35016674999997)
  });
  const bounds = new google.maps.LatLngBounds(null);
  // sample data
  var rows = [
    [-87.8199, 42.621],
    [-87.4934, 42.123],
    [-87.815094, 42.558089],
  ]
  // note that .forEach is asynchronous
  //rows.forEach(function(pair) {
  for (var i = 0; i < rows.length; i++) {
    var pair = rows[i];
    const boundary = new google.maps.LatLng(pair[1], pair[0]);
    var marker = new google.maps.Marker({
      position: boundary,
      map: map
    })
    bounds.extend(boundary);
  } //);
  var rect1 = new google.maps.Rectangle({
    bounds: bounds,
    fillOpacity: 0.5,
    fillColor: "blue",
    map: map
  })
  setMapBounds(map, bounds, /* map.getCenter() */ );

  google.maps.event.addDomListener(window, "resize", function() {
    google.maps.event.trigger(map, "resize");
    setMapBounds(map, bounds, map.getCenter());
  });

  const style = [{
    featureType: 'all',
    elementType: 'all',
    stylers: [{
      saturation: 44
    }]
  }];

  const styledMapType = new google.maps.StyledMapType(style, {
    map: map,
    name: 'Styled Map'
  });

  map.mapTypes.set('map-style', styledMapType);
  map.setMapTypeId('map-style');
}

function setMapBounds(map, bounds, center) {
  console.log("bounds=" + bounds.toUrlValue(6));
  map.fitBounds(bounds);

  if (center) {
    google.maps.event.addListenerOnce(map, "bounds_changed",
      (function(event) {
        // Reset center since fitBounds can change it
        map.setCenter(center);
      })
    );
  }
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>