尽管范围很小,但Google Maps fitBounds()会将地图缩放得很远

时间:2018-08-30 23:11:01

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

我正在使用Google的Fusion Tables API,以便在地图上显示县的轮廓,然后将其适合任何视口。 fitBounds()到目前为止对于以前的地图都有效,但是当我在Fusion Tables图层中添加时,一切开始变得奇怪。以下代码最终将地图缩小以查看整个北美,尽管纬度范围在-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 个答案:

答案 0 :(得分:1)

几个问题:

  1. 看起来像pair[0], pair[1]应该是pair[1], pair[0](例如您的坐标是经度和纬度,而google.maps.LatLng则期望纬度和经度)。
    纬度-87低于南极附近的可用磁贴。如果翻转它们,我会在密尔沃基附近找到位置。 (与您的地图中心中心比较:new google.maps.LatLng(42.9065288383437,-88.35016674999997))

  2. 如果this map.setCenter(center);不是边界的中心,则
  3. setMapBounds会引起center方法的怪异。

proof of concept fiddle

screenshot of map displaying your sample data

代码段:

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>