ESRI ArcGIS:平移和缩放以适合标记

ESRI ArcGIS: Pan and Zoom to fit markers

我是 ESRI ArcGIS 的新手。我们正在考虑替代 Google 地图。在此 post https://www.esri.com/arcgis-blog/products/js-api-arcgis/announcements/migrating-from-google-maps-javascript-api-to-arcgis-api-for-javascript/ 中,他们解释了迁移到 ArcGIS 应该是多么容易,但似乎超出了他们提供的示例,我被卡住了。

我在地图中加载了一堆标记。我正在尝试让地图平移和缩放以适合所有标记,但我一直无法找到执行此操作的任何代码。

在 Google 地图上我会这样做:

myMap.options.center = new google.maps.LatLng(0,0);
myMap.options.mapTypeId = google.maps.MapTypeId[myMap.options.mapTypeId];
myMap.bounds = new google.maps.LatLngBounds();
myMap.map = new google.maps.Map(document.getElementById('cat-map'), myMap.options);

google.maps.event.addListenerOnce(myMap.map, 'bounds_changed', function(event){
    myMap.map.fitBounds(myMap.bounds);
    myMap.map.panToBounds(myMap.bounds);
});

for (var i = 0; i < myMap.items.length; i++) {
    var itemLatlng = new google.maps.LatLng(myMap.items[i].lat, myMap.items[i].lng);
    myMap.bounds.extend(itemLatlng);
    new google.maps.Marker({
        position: itemLatlng,
        map: myMap.map,
    });
}

但我一直无法在 ESRI ArcGIS 上找到等效项。

有人指导一下吗?

你的想法是对的。在 ArcGIS 中,API Extent class 具有 union 扩展调用方以将几何范围传递作为参数包含在内的方法。因为您正在使用 Point 不能使用 union 方法,Point 范围是 null。但不用担心,您只需自己迭代图形并扩展范围就可以实现这一目标。

看看我为你做的这个例子,使用你问题的 link 作为基础,

<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>ArcGIS API for JavaScript Hello World App</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
    #zoomBtn {
      margin: .5rem;
    }
  </style>

  <link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/css/main.css">
  <script src="https://js.arcgis.com/4.15/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      'esri/geometry/Extent'
    ], function (Map, MapView, Extent) {

      const map = new Map({
        basemap: "streets-navigation-vector"
      });

      const view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 12,
        center: {
          latitude: 32.7353,
          longitude: -117.1490
        }
      });

      function popupContent (feature) {
        const div = document.createElement("div");
        div.innerHTML = `Address: ${feature.graphic.attributes.addrs} <br>` +
          `<a href='${feature.graphic.attributes.url}'>Web</a>`;
        return div;
      }

      function toGraphic(color, lon, lat, title, addrs, url) {
        return {
          symbol: {
            type: "text",
            color,
            text: "\ue61d",
            font: {
              size: 30,
              family: "CalciteWebCoreIcons"
            }
          },
          geometry: {
            type: "point",
            longitude: lon,
            latitude: lat
          },
          attributes: {
            title,
            addrs,
            url
          },
          popupTemplate: {
            title: '{title}',
            outfields: ['*'],
            content: popupContent
          }
        }
      }

      const graphics = [
        toGraphic(
          'gray',
          -117.1560632,
          32.727482,
          'Automotive Museum',
          '2080 Pan American Plaza, San Diego, CA 92101, United States',
          'http://sdautomuseum.org/'
        ),
        toGraphic(
          'gray',
          -117.1763293,
          32.7136902,
          'USS Midway Museum',
          '910 N Harbor Dr, San Diego, CA 92101, United States',
          'http://www.midway.org/'
        ),
        toGraphic(
          'blue',
          -117.2284536,
          32.7641112,
          'SeaWorld',
          '500 Sea World Dr, San Diego, CA 92109, United States',
          'https://seaworld.com/san-diego'
        ),
        toGraphic(
          'green',
          -117.1557741,
          32.7360032,
          'Zoo',
          '2920 Zoo Dr, San Diego, CA 92101, United States',
          'https://zoo.sandiegozoo.org/'
        )
      ];

      view.graphics.addMany(graphics);

      function maxExtent(graphics) {
        const e = graphics
          .map(g => g.geometry)
          .reduce(
            (acc, geom) => (
              {
                xmin: Math.min(acc.xmin, geom.longitude),
                ymin: Math.min(acc.ymin, geom.latitude),
                xmax: Math.max(acc.xmax, geom.longitude),
                ymax: Math.max(acc.ymax, geom.latitude)
              }
            ),
            {
              xmin: Number.MAX_SAFE_INTEGER,
              ymin: Number.MAX_SAFE_INTEGER,
              xmax: Number.MIN_SAFE_INTEGER,
              ymax: Number.MIN_SAFE_INTEGER
            }
          );
        return new Extent(e);
      }

      document.getElementById('zoomBtn')
        .addEventListener(
          'click',
          _ => {
            const ext = maxExtent(graphics);
            console.log(`View Extent: ${JSON.stringify(view.extent)} Graphics Extent:${JSON.stringify(ext)}`);
            view.extent = ext.expand(2); // expand a little so border points shows
          }
        );

    });
  </script>
</head>

<body>
  <div class="esri-widget">
    <button id="zoomBtn" class="esri-button">Zoom To Graphics</button>
  </div>
  <div id="viewDiv"></div>
</body>

</html>