如何实现地图自动缩放并移动到中心点
=================

#### 问题现象

怎么实现自动调整缩放和移动到中心点，将所有的Marker全部显示在屏幕上？

#### 效果预览

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/2b/v3/5hIwmpF9QD2O-cqP73rAmQ/zh-cn_image_0000002628394374.png?HW-CC-KV=V1&HW-CC-Date=20260709T134309Z&HW-CC-Expire=86400&HW-CC-Sign=BF66FCF5C207BF9C39C1D416509BDF54C2D412E93E6FA2757E10E50F681AFB17 "点击放大")

#### 背景知识

*   Map Kit（地图服务）为开发者提供强大而便捷的地图能力，开发前需开通地图服务，参考：[开通地图服务](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/map-config-agc#section16133115441516)。
*   LatLngBoundsUtils类的[include](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/map-map-latlngboundsutils#section184215814215)：获取一个包含指定位置的LatLngBounds对象。
*   [moveCamera](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/map-map-mapcomponentcontroller#section141021341974)：更新相机状态。

#### 解决方案

1.  使用LatLngBoundsUtils类的include接口获取一个包含所有标记点的LatLngBounds对象。
    
    getLatLngBounds(): mapCommon.LatLngBounds | undefined {
      let latLngs: Array<mapCommon.LatLng\> = \[{
        latitude: 12,
        longitude: 110
      }, {
        latitude: 31.18,
        longitude: 121.43
      }, {
        latitude: 8,
        longitude: 90
      }\];
      let resultBounds: mapCommon.LatLngBounds | undefined;
      for (let index \= 0; index < latLngs.length; index++) {
        let markerOptions: mapCommon.MarkerOptions \= {
          position: {
            latitude: latLngs\[index\].latitude,
            longitude: latLngs\[index\].longitude
          },
          rotation: 0,
          visible: true,
          zIndex: 0,
          alpha: 0.9,
          anchorU: 0.5,
          anchorV: 1,
          clickable: true,
          draggable: true,
          flat: false
        };
    
        this.mapController?.addMarker(markerOptions).catch(() \=\> {
          console.error('addMarker error');
        });
        resultBounds \= map.LatLngBoundsUtils.include(latLngs\[index\], resultBounds);
      }
      return resultBounds;
    }
    
2.  通过移动地图相机的方式设置地图显示区域。
    
    aboutToAppear(): void {
      try {
      let displayClass \= display.getDefaultDisplaySync();
      this.mapHeight \= this.getUIContext().px2vp(displayClass.height);
    } catch (error) {
      console.error(\`getDefaultDisplaySync error. Code is ${error.code}, message is ${error.message}.\`);
    }
    
    this.mapOptions \= {
      position: {
        target: {
          longitude: 121.47, latitude: 31.23
        },
        zoom: 11
      }
    };
    
    _//_ _地图初始化的回调_
    this.callback \= async (err, mapController) \=\> {
      if (!err) {
        this.mapController \= mapController;
      }
    };
    }
    
    build() {
      Stack({ alignContent: Alignment.Bottom }) {
        Column() {
          MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback })
            .height(this.mapHeight)
            .expandSafeArea(\[SafeAreaType.SYSTEM\], \[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM\]);
        }
        .width('100%');
    
        Button('LatLngBounds')
          .onClick(() \=\> {
            if (this.getLatLngBounds()) {
              let cameraUpdate: map.CameraUpdate \= map.newLatLngBounds(this.getLatLngBounds(), 100);
              _// 移动相机_
              this.mapController?.moveCamera(cameraUpdate);
            }
          })
          .margin({ bottom: -40 });
      }
      .height('100%')
      .ignoreLayoutSafeArea();
    }
    

完整示例代码如下：

import { MapComponent, mapCommon, map } from '@kit.MapKit';
import { AsyncCallback } from '@kit.BasicServicesKit';
import { display } from '@kit.ArkUI';

@Entry
@Component
struct MarkerPage {
  private mapOptions?: mapCommon.MapOptions;
  private mapController?: map.MapComponentController;
  private callback?: AsyncCallback<map.MapComponentController\>;
  @State mapHeight: number \= 0;

  getLatLngBounds(): mapCommon.LatLngBounds | undefined {
    let latLngs: Array<mapCommon.LatLng\> = \[{
      latitude: 12,
      longitude: 110
    }, {
      latitude: 31.18,
      longitude: 121.43
    }, {
      latitude: 8,
      longitude: 90
    }\];
    let resultBounds: mapCommon.LatLngBounds | undefined;
    for (let index \= 0; index < latLngs.length; index++) {
      let markerOptions: mapCommon.MarkerOptions \= {
        position: {
          latitude: latLngs\[index\].latitude,
          longitude: latLngs\[index\].longitude
        },
        rotation: 0,
        visible: true,
        zIndex: 0,
        alpha: 0.9,
        anchorU: 0.5,
        anchorV: 1,
        clickable: true,
        draggable: true,
        flat: false
      };

      this.mapController?.addMarker(markerOptions).catch(() \=\> {
        console.error('addMarker error');
      });
      resultBounds \= map.LatLngBoundsUtils.include(latLngs\[index\], resultBounds);
    }
    return resultBounds;
  }

  aboutToAppear(): void {
    try {
      let displayClass \= display.getDefaultDisplaySync();
      this.mapHeight \= this.getUIContext().px2vp(displayClass.height);
    } catch (error) {
      console.error(\`getDefaultDisplaySync error. Code is ${error.code}, message is ${error.message}.\`);
    }

    this.mapOptions \= {
      position: {
        target: {
          longitude: 121.47, latitude: 31.23
        },
        zoom: 11
      }
    };

   _ // 地图初始化的回调_
    this.callback \= async (err, mapController) \=\> {
      if (!err) {
        this.mapController \= mapController;
      }
    };
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      Column() {
        MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback })
          .height(this.mapHeight)
          .expandSafeArea(\[SafeAreaType.SYSTEM\], \[SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM\]);
      }
      .width('100%');

      Button('LatLngBounds')
        .onClick(() \=\> {
          if (this.getLatLngBounds()) {
            let cameraUpdate: map.CameraUpdate \= map.newLatLngBounds(this.getLatLngBounds(), 100);
          _  // 移动相机_
            this.mapController?.moveCamera(cameraUpdate);
          }
        })
        .margin({ bottom: -40 });
    }
    .height('100%')
    .ignoreLayoutSafeArea();
  }
}