Angular + Ionic + ArcGIS 实现地图点位筛选;监听地图缩放级别,动态修改图例大小

目录

一. 需求介绍

二. 实现过程

2.1 初始化地图

2.2 实现图例展开折叠及复选功能

2.2.1 图例展开折叠

2.2.2 图例复选框

2.2.3 源码 

2.3 初始化图层、显示弹框、打点、清除打点

2.3.1 初始化图层

2.3.2 实现弹框展示隐藏

2.3.3 实现点位筛选(分类)

2.3.4 打点

2.3.5 移除地图中的所有图层(清除打点)

2.3.6 地图整体点击事件

2.3.7 源码

2.4 监听地图缩放级别变化,动态设置图例大小


一. 需求介绍

地图加载后,需要自动定位到,尽量包裹所有点位的范围

图例可以展开折叠

需要筛选点位,且每次筛选后,都会重新进行范围确认

点击点位后,可以在屏幕下方弹出弹框,显示点位详细信息

点击地图的其他位置,弹框可以隐藏

二. 实现过程

2.1 初始化地图

新建地图页面:ionic g page map

引入封装好的 地图组件 以及 地图服务

在新建的地图页面中,修改 .html 文件,调用 地图加载完毕 的方法

该方法主要用于:实例化地图对象,并在拥有对象的基础上,进行诸如 打点 的其他操作

  <!-- 引入地图组件 -->
  <div style="width: 100%; height: 100%">
    <ths-map (onMapLoaded)="onMapLoaded($event)" style="width: 100%; height: 100%"> </ths-map>
  </div>

  /**
   * 地图加载完毕
   * @param map 事件对象
   */
  onMapLoaded(map: any): void {
    this.mapView = map; // 地图对象
    ...
  }

2.2 实现图例展开折叠及复选功能

2.2.1 图例展开折叠

通过调整 legendUp 属性,决定图例的 展开/收起 图标,每次点击后,都会让 legend 切换

通过调整 legendUp 属性,决定图例的 具体列表 是否显示

不给图例列表设置宽度,就能够实现图例展开收起后,图例标题宽度自适应收起来

2.2.2 图例复选框

复选框绑定了,图层列表的显示状态:[(ngModel)]="isShowList.dlLayer

监听复选框改变事件 (ionChange),根据图层列表的展示状态,决定是 添加图层,还是清除图层

2.2.3 源码 

<!-- 图例 -->
  <ion-list class="legend" lines="full">
    <!-- 图例标题 -->
    <ion-item class="bg-title" lines="none">
      <ion-label class="title-center">图例</ion-label>
      <ion-icon name="arrow-dropdown" color="medium" *ngIf="legendUp" (click)="changeLegned()"></ion-icon>
      <ion-icon name="arrow-dropup" color="medium" *ngIf="!legendUp" (click)="changeLegned()"></ion-icon>
    </ion-item>
    <!-- 具体图例组 -->
    <ion-item-group *ngIf="legendUp">
      <ion-item lines="none">
        <!-- 复选按钮 -->
        <ion-checkbox slot="start" [(ngModel)]="isShowList.dlLayer"
          (ionChange)="isShowList.dlLayer?addDLLayerPoint():clearLayer('dlLayer')"
        ></ion-checkbox>
        <!-- 图例图片 -->
        <ion-thumbnail slot="start">
          <ion-img src="assets/images/source_3.png"></ion-img>
        </ion-thumbnail>
        <ion-label>道路</ion-label>
      </ion-item>
      ...
    </ion-item-group>

  // 图例展开折叠状态
  public legendUp: boolean = true;

  /**
   * 图例展开折叠状态切换事件
   */
  changeLegned(): void {
    this.legendUp = !this.legendUp;
  }

  // 图层列表展示状态
  public isShowList: { [propName: string]: boolean } = {
    dlLayer: true,
    jzgdLayer: true,
    dcmtLayer: true,
    jbcLayer: true,
  };

 

 

2.3 初始化图层、显示弹框、打点、清除打点

2.3.1 初始化图层

初始化图层,必须在拥有地图对象之后才能进行

也就是在  onMapLoaded() 方法中,声明地图对象之后,执行初始化图层操作

初始化图层:this.thsMapService.addGraphicsLayer()

2.3.2 实现弹框展示隐藏

初始化图层中,接受三个参数,其中第三个是 点击事件回调函数

点击事件回调函数中的 event,用于存储图层的全部信息,并且可以将这个图层全部信息传出

比如,点击某个点位出现弹框,我想获取这个点位的全部信息,就是通过此回调函数,接受具体信息,并进行格式化输出的

我个人觉得,这个回调函数,就是在初始化图层,并执行打点操作后,再调用的,用于接受打点之后的图层信息,然后再将这些信息进行展示

  <!-- 弹框 -->
  <ion-list class="pop" lines="full" *ngIf="isPopShow">
    <ion-item>
      <ion-label class="title">{{popInfo.POINT_NAME || "--"}}</ion-label>
    </ion-item>
    <img src="assets/images/da-icon.png" *ngIf="popInfo.DUST_LEVEL === '好'" />
    <img src="assets/images/yu-icon.png" *ngIf="popInfo.DUST_LEVEL === '差'" />
  </ion-list>

2.3.3 实现点位筛选(分类)

实现点位筛选的本质:将点位进行分类,打在不同的图层上

初始化图层方法,返回的是 promise对象,可以赋值给 图层对象 this.dlLayer = res;

根据图层展示状态:(ionChange)="isShowList.dcmtLayer?addDCMTLayerPoint():clearLayer('dcmtLayer')"

  • 如果是展示的(图例选中),就在图层上进行打点操作
  • 如果是不展示的(图例未选中),就在图层上清除已有的图层信息

2.3.4 打点

需要先获取所需要的点位信息,依次执行 addPoint(),将点位添加到图层

值得注意的是,每次这个方法只能添加一个点,可以通过 for循环 多次执行该打点操作 Number(res.data[i].LONGITUDE),

打点结束后,应该根据打点位置,重新确定显示范围:this.thsMapService.setExtent(this.mapView, minX, minY, maxX, maxY);

2.3.5 移除地图中的所有图层(清除打点)

调用方法清除打点,结束之后,记得更改图层当前的显示状态

2.3.6 地图整体点击事件

比如点击点位后,出现弹框,点击地图的其他部分应该隐藏弹框,这时候就需要地图整体点击事件

除了点位之外,地图其他部分被点,就会触发这个事件

地图整体点击事件传回来一个对象 e,包含了地图的全部信息

其中有一项 e.graphic如果是 undefined,就意味着没有点击点位,可以根据这个,来判定弹框是否隐藏

注意,这个事件也需要在 onMapLoaded() 方法中,声明地图对象之后执行

2.3.7 源码

  // 不同的图层对象
  private dlLayer: any;
  // 不同的图层对象
  private jzgdLayer: any;
    ...

    // 初始化道路图层
    this.thsMapService
      .addGraphicsLayer(this.mapView, 'dlLayer', (event) => {
        this.addPopInfo(event);
      })
      .then((res) => {
        this.dlLayer = res;
        if (this.isShowList.dlLayer) {
          // 添加道路图层点位
          this.addDLLayerPoint();
        }
      });

    // 地图整体点击事件
    this.mapView.on('click', (e) => {
      this.mapClick(e);
    });

  /**
   * 移除图层中的所有图形
   * @param layerName 图层名称
   */
  clearLayer(layerName: string): void {
    // 调用服务,清除对应图层信息
    this.thsMapService.clearLayer(this.mapView, layerName);
    // 更改显示状态
    this.isShowList[layerName] = false;
  }

  /**
   * 添加图层点位
   * @param params 添加点位的请求参数
   * @param layer 添加点位的图层
   * @param imgSrc 添加点位的图片地址
   */
  addPoint(params: object, layer: object, imgSrc: string): void {
    // 请求点位
    this.tabEnvService.getDutsListData(params, false, (res) => {
      // 初始化范围
      let minX = 0;
      let maxX = 0;
      let minY = 0;
      let maxY = 0;

      // 进行道路打点(每次只能打一个,所以要通过 for循环)
      for (let i = 0; i < res.data.length; i++) {
        // 每次打点前 进行地图区域范围更新
        if (minX === 0 || res.data[i].LONGITUDE < minX) {
          minX = Number(res.data[i].LONGITUDE);
        }
        if (maxX === 0 || res.data[i].LONGITUDE > maxX) {
          maxX = Number(res.data[i].LONGITUDE);
        }
        if (minY === 0 || res.data[i].LATITUDE < minY) {
          minY = Number(res.data[i].LATITUDE);
        }
        if (maxY === 0 || res.data[i].LATITUDE > maxY) {
          maxY = Number(res.data[i].LATITUDE);
        }

        this.thsMapService.addMarker(
          // 经度
          Number(res.data[i].LONGITUDE),
          // 纬度
          Number(res.data[i].LATITUDE),
          layer,
          imgSrc,
          20,
          20,
          0,
          0,
          4326,
          res.data[i]
        );
      }
      // console.log(minX, minY, maxX, maxY);
      // 根据地图点位 确定大致地图范围
      this.thsMapService.setExtent(this.mapView, minX, minY, maxX, maxY);
    });
  }

  /**
   * 添加道路图层点位
   */
  addDLLayerPoint(): void {
    this.addPoint(this.params[1], this.dlLayer, '/assets/images/source_3.png');
  }

  /**
   * 除了打点位置外,其余位置的地图点击事件
   */
  mapClick(e: any): void {
    // console.log(e);
    // graphic._graphicsLayer
    if (e.graphic === undefined) {
      this.isPopShow = false;
    }
  }

2.4 监听地图缩放级别变化,动态设置图例大小

移动端地图使用的是 arcgis js(没有点哦),版本是 3.x

注意: 版本3.x 和 版本4.x 同步更新,他们是两个体系,而不是我原来理解的版本升级,直接搜 arcgis 出现的不是我们需要的 版本3.x,一定要注意搜索正确的版本

 

zoom-end :缩放执行完毕后,触发的事件

  /**
   * 注册地图级别发生改变的事件
   * @callback cb
   */
  mapLevelChanged(cb: () => void) {
    this.map.on('zoom-end', cb);
  }

  /**
   * 获取地图当前级别
   */
  getMapLevel() {
    return this.map.getLevel();
  }


// 监听图层级别变化,动态设置点位图标的大小
pageData.mapView.mapLevelChanged(() => {
  const currentLevel = pageData.mapView.getMapLevel();
  console.log('当前地图缩放级别为:', currentLevel);
  if (currentLevel <= 9) {
    setMapPointClickStyle(pageData.mapLayer.companyLayer.value, null, 1);
  } else if (currentLevel > 9 && currentLevel <= 10) {
    setMapPointClickStyle(pageData.mapLayer.companyLayer.value, null, 10);
  } else if (currentLevel > 10 && currentLevel <= 11) {
    setMapPointClickStyle(pageData.mapLayer.companyLayer.value, null, 15);
  } else if (currentLevel > 11 && currentLevel <= 12) {
    setMapPointClickStyle(pageData.mapLayer.companyLayer.value, null, 20);
  } else if (currentLevel > 12 && currentLevel <= 13) {
    setMapPointClickStyle(pageData.mapLayer.companyLayer.value, null, 30);
  } else {
    setMapPointClickStyle(pageData.mapLayer.companyLayer.value, null, 35);
  }
})
Angular是一个流行的JavaScript框架,用于构建Web应用程序。Ionic是基于Angular的开源移动应用开发框架,它提供了一套UI组件和具,帮助开发者构建跨平台的移动应用程序。 Swiper是一个流行的移动端滑动组件库,它提供了丰富的滑动效果和交互功能,可以用于创建漂亮的轮播图、图片浏览器等。 结合AngularIonic,你可以轻松地集成Swiper组件到你的移动应用中。首先,你需要在你的Angular项目中安装Swiper组件库。可以使用npm命令来安装: ``` npm install swiper --save``` 安装完成后,你可以在你的Ionic组件中引入Swiper组件,并在模板中使用它。以下是一个简单的示例: ```typescriptimport { Component } from '@angular/core'; import SwiperCore, { Navigation, Pagination } from 'swiper/core'; SwiperCore.use([Navigation, Pagination]); @Component({ selector: 'app-swiper', template: ` <swiper [navigation]="true" [pagination]="true"> <ng-template swiperSlide>Slide1</ng-template> <ng-template swiperSlide>Slide2</ng-template> <ng-template swiperSlide>Slide3</ng-template> </swiper> `, }) export class SwiperComponent {} ``` 在上面的示例中,我们首先引入了Swiper组件库,并注册了所需的Swiper模块(例如Navigation和Pagination)。然后,在组件的模板中,我们使用`<swiper>`标签创建了一个Swiper实例,并在内部添加了三个滑动的内容块。 你可以根据你的需求自定义Swiper的配置和样式。更多关于Swiper的用法和配置,你可以参考Swiper官方文档。 希望这可以帮助到你!如果你还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lyrelion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值