目录

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

问题现象

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

效果预览

背景知识

解决方案

  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();
  }
}