放大 Google 地图数据层

Zoom On Google Maps Data Layer

我在集中和缩放数据层中的信息时遇到问题。我尝试使用此处建议的方法:Whosebug question: zoom to geojson polygons bounds in Google Maps API v3。我最初仍然放大到他所在的同一个地方,在贝克岛附近的太平洋中的某个地方。我正在从服务器加载一个 GeoJson 对象,它可以正确显示。我的代码:

function loadMap () {
    var m = document.getElementById("googleMap");
    var mapProp = { 
        disableDoubleClickZoom: true, 
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(m, mapProp);

    map.data.addListener('addfeature', function(e) {            
        var bounds = new google.maps.LatLngBounds();
        processPoints(e.feature.getGeometry(), bounds.extend, bounds);

        map.setCenter(bounds.getCenter());
        map.fitBounds(bounds);
    });

    var geoJsonObject = {
        type: "FeatureCollection",
        features: [
           {
              type: "Feature",
              properties: {},
              geometry: {
                  type: "MultiPolygon",
                  coordinates: [
                      [[[-86.80795499999999, 36.146389], [-86.80605800006222, 36.14733499995285], [-86.806471, 36.147928], [-86.80836699994975, 36.14697700000941], [-86.80795499999999, 36.146389]]],
                      [[[-86.803842, 36.143921999999996], [-86.803761, 36.144005], [-86.80374600001942, 36.1441770000485], [-86.804918, 36.1458], [-86.805436, 36.145536], [-86.80621699999999, 36.146585], [-86.80755499999131, 36.145895000035935], [-86.807208, 36.145385999999995], [-86.806328, 36.144205], [-86.803842, 36.143921999999996]]]
                  ]
              }
           }
        ]
    };
    map.data.addGeoJson(geoJsonObject);
}

function processPoints(geometry, callback, thisArg) {
    if(geometry instanceof google.maps.LatLng) {
        callback.call(thisArg, geometry);
    }
}

还有其他建议吗?

您修改后的 processPoints 例程不处理多边形。

你的:

function processPoints(geometry, callback, thisArg) {
    if(geometry instanceof google.maps.LatLng) {
        callback.call(thisArg, geometry);
    }
}

来自referenced answer on SO

function processPoints(geometry, callback, thisArg) {
    if (geometry instanceof google.maps.LatLng) {
        callback.call(thisArg, geometry);
    } else if (geometry instanceof google.maps.Data.Point) {
        callback.call(thisArg, geometry.get());
    } else {
        geometry.getArray().forEach(function (g) {
            processPoints(g, callback, thisArg);
        });
    }
}

工作代码片段:

window.addEventListener("load", loadMap);
var map;

function loadMap() {
  var m = document.getElementById("googleMap");
  var mapProp = {
    disableDoubleClickZoom: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var map = new google.maps.Map(m, mapProp);
  var bounds = new google.maps.LatLngBounds();
  map.data.addListener('addfeature', function(e) {
    processPoints(e.feature.getGeometry(), bounds.extend, bounds);
    map.setCenter(bounds.getCenter());
    map.fitBounds(bounds);
  });

  var geoJsonObject = {
    type: "FeatureCollection",
    features: [{
      type: "Feature",
      properties: {},
      geometry: {
        type: "MultiPolygon",
        coordinates: [
          [
            [
              [-86.80795499999999, 36.146389],
              [-86.80605800006222, 36.14733499995285],
              [-86.806471, 36.147928],
              [-86.80836699994975, 36.14697700000941],
              [-86.80795499999999, 36.146389]
            ]
          ],
          [
            [
              [-86.803842, 36.143921999999996],
              [-86.803761, 36.144005],
              [-86.80374600001942, 36.1441770000485],
              [-86.804918, 36.1458],
              [-86.805436, 36.145536],
              [-86.80621699999999, 36.146585],
              [-86.80755499999131, 36.145895000035935],
              [-86.807208, 36.145385999999995],
              [-86.806328, 36.144205],
              [-86.803842, 36.143921999999996]
            ]
          ]
        ]
      }
    }, {
      type: "Feature",
      properties: {},
      geometry: {
        type: "MultiPolygon",
        coordinates: [
          [
            [
              [-86.82083, 36.148815],
              [-86.820293, 36.149196],
              [-86.819585, 36.148572],
              [-86.819971, 36.148087],
              [-86.82083, 36.148815]
            ]
          ]
        ]
      }
    }]
  };
  map.data.addGeoJson(geoJsonObject);
}

function processPoints(geometry, callback, thisArg) {
  if (geometry instanceof google.maps.LatLng) {
    callback.call(thisArg, geometry);
  } else if (geometry instanceof google.maps.Data.Point) {
    callback.call(thisArg, geometry.get());
  } else {
    geometry.getArray().forEach(function(g) {
      processPoints(g, callback, thisArg);
    });
  }
}
html,
body,
#googleMap {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="googleMap"></div>

@geocodezip 的回答对我不起作用。由于 addfeature 事件将针对 JSON 中的每个功能触发。这个答案向我们展示的是它将重置 LatLngBounds() 实例,从而重置边界框的扩展。

我正在使用一个名为 d3.js 的附加 javascript 库(顺便说一句,非常方便的库),它提供了一个可以读取 Geo[=25= 的 geo class ] 并生成 Google 地图实例的 fitBounds() 方法所需的边界框坐标。

myNamespace.getLogs().then(function (resp) {
    var logData = myNamespace.map.data.addGeoJson(resp);
    var jsonBounds = d3.geo.bounds(resp);
    myNamespace.mapBounds = new google.maps.LatLngBounds({
        lat: jsonBounds[0][1],
        lng: jsonBounds[0][0]
    }, {
        lat: jsonBounds[1][1],
        lng: jsonBounds[1][0]
    });
    myNamespace.map.fitBounds(myNamespace.mapBounds);
});

这将生成一对数组项的数组,一个用于 SW,一个用于 NE。例如:

Array([Array([sw_lng, sw_lat]), Array([ne_lng, ne_lat])])

在这里查看我的回答。

上面建议的递归处理函数很聪明,但是不需要手动处理各种Geometry类型。

映射 API(至少从今天的 V3.26 开始)支持 Data.Geometry.prototype.forEachLatLng(),它抽象出各种 Geometry 类型。

鉴于您已经将 geoJSON 导入 map.data,重新缩放地图以适合 ("fit-to-bounds") 很容易:

var bounds = new google.maps.LatLngBounds(); 
map.data.forEach(function(feature){
  feature.getGeometry().forEachLatLng(function(latlng){
     bounds.extend(latlng);
  });
});

map.fitBounds(bounds);

如果您的功能已经因为其他原因(例如设置样式)进行迭代,您可以将此代码添加到现有循环中以提高效率。