目录

如何修改地图的折线纹理间距

问题现象

使用地图服务addPolyline添加箭头样式的纹理,会出现折线上箭头之间的间距太小、箭头过于密集的情况,如何修改折线纹理的间距?

背景知识

解决方案

方案逻辑:通过customTexture配置折线纹理时,折线上纹理图片的间距默认为线宽的2倍,并且没有接口可以直接设置纹理图片的间距。而使用customTextures配置纹理时,添加的纹理图片间没有间距,可以配置纹理图片为带纯色底色的纹理,调整图片宽度,使图片之间的真实纹理的距离为预期的宽度。如下图所示:

  1. 获取路线的坐标点列表。
  2. 添加调整后的纹理图到customTextures列表。
    let customTextures: Array<ResourceStr | image.PixelMap> = new Array();
    customTextures.push('icon/arrow.png'); // 设置为目标纹理图片
  3. 配置customTextureIndexes纹理图片索引列表,索引值为customTextures纹理图列表中希望添加的纹理图的对应索引,列表中需要设置每个坐标线段的目标纹理图片索引值。如果规划整条路线为相同的纹理图时,则每个坐标线段配置相同的图片索引值,本案例场景全部配置为0。
    let cusIndexNumber: Array<number> = new Array();
    for (let i = 0; i < this.points.length; ++i) {
      cusIndexNumber.push(0);
    }
  4. 配置MapPolylineOptions中points、customTextures、customTextureIndexes的值为步骤1/2/3中的值,并添加折线图。
    let polylineOption: mapCommon.MapPolylineOptions = {
      points: this.points,
      clickable: true,
      startCap: mapCommon.CapStyle.BUTT,
      endCap: mapCommon.CapStyle.BUTT,
      jointType: mapCommon.JointType.BEVEL,
      width: 20,
      customTextures: customTextures,
      customTextureIndexes: cusIndexNumber
    };
    
    await this.mapController?.addPolyline(polylineOption);

    效果图如下:

完整代码如下:

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

@Entry
@Component
struct CustomTexture {
  private mapOptions?: mapCommon.MapOptions;
  private mapController?: map.MapComponentController;
  private callback?: AsyncCallback<map.MapComponentController>;
  @State points: mapCommon.LatLng[] = [];
  @State mapHeight: number = 0;

  async aboutToAppear() {
    let displayClass = display.getDefaultDisplaySync();
    this.mapHeight = this.getUIContext().px2vp(displayClass.height);
    // 地图初始化参数
    this.mapOptions = {
      position: {
        target: {
          latitude: 31.984410259206815,
          longitude: 118.76625379397866
        },
        zoom: 18
      }
    };

    this.callback = async (err, mapController) => {
      if (!err) {
        this.mapController = mapController;

      }
    };
  }

  async addRoute() {
    // 实际使用时根据获取的路线坐标进行赋值
    this.points = [{ longitude: 116.31084, latitude: 39.992281 },
      { longitude: 116.31084, latitude: 39.99218 },
      { longitude: 116.31083, latitude: 39.99215 },
      { longitude: 116.31081, latitude: 39.99212 },
      { longitude: 116.31076, latitude: 39.99205 },
      { longitude: 116.31075, latitude: 39.9920199 },
      { longitude: 116.31075, latitude: 39.99191 },
      { longitude: 116.31074, latitude: 39.99187 },
      { longitude: 116.31075, latitude: 39.9918 },
      { longitude: 116.31076, latitude: 39.99176 },
      { longitude: 116.31079, latitude: 39.99172 },
      { longitude: 116.31082, latitude: 39.9917 },
      { longitude: 116.31084, latitude: 39.99166 },
      { longitude: 116.31085, latitude: 39.9914599 },
      { longitude: 116.31085, latitude: 39.99135 },
      { longitude: 116.31081, latitude: 39.9913 },
      { longitude: 116.31078, latitude: 39.99129 },
      { longitude: 116.31067, latitude: 39.99129 },
      { longitude: 116.31054, latitude: 39.99128 },
      { longitude: 116.31053, latitude: 39.9911699 }];
    let customTextures: Array<ResourceStr | image.PixelMap> = new Array();
    customTextures.push('icon/arrow.png'); // 设置为目标纹理图片
    let cusIndexNumber: Array<number> = new Array();
    for (let i = 0; i < this.points.length; ++i) {
      cusIndexNumber.push(0);
    }

    let polylineOption: mapCommon.MapPolylineOptions = {
      points: this.points,
      clickable: true,
      startCap: mapCommon.CapStyle.BUTT,
      endCap: mapCommon.CapStyle.BUTT,
      jointType: mapCommon.JointType.BEVEL,
      width: 20,
      customTextures: customTextures,
      customTextureIndexes: cusIndexNumber
    };

    await this.mapController?.addPolyline(polylineOption);
    let cameraUpdate = map.newLatLng(polylineOption.points[0]);
    this.mapController?.moveCamera(cameraUpdate);
  }

  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('查看路线')
        .onClick(() => {
          this.addRoute();
        })
        .margin({ bottom: 20 })
    }.height('100%')
    .ignoreLayoutSafeArea()
  }
}

常见FAQ

Q:为什么把MapPolylineOptions中的color设置为Color.Red不生效?

A:color参数类型为number,只能输入ARGB格式。