地图服务 ArcGIS API for JavaScript基础用法全解析

地图服务 ArcGIS API for JavaScript基础用法全解析

前言

在接触ArcGIS之前,开发web在线地图时用过Leaflet来构建地图应用,作为一个轻量级的开源js库,在我使用下来Leaflet还有易懂易用的API文档,是个很不错的选择。在接触使用ArcGIS后,我发现其API文档的阅读体验很不尽人意。尽管它提供了详尽的接口描述和参数说明,但由于文档的复杂性和缺乏直观的示例,对于初学者来说可能难以理解和应用,经过几天的努力,手写了多个helloworld,并终于整理出了地图的基本用法。包括,地图打点、自定义点popup,折线栅栏、区域覆盖物、热力图、以及地图上的操作(区域多边形圈选、地图绘制)。demo已上传git,具体源码可直接查看:gitee.com/fcli/arcgis...

地图初始化

1、首先我们需要准备一个地图服务地址,安装@arcgis/core依赖包

sql 复制代码
yarn add @arcgis/core

2、初始化一个地图

arduino 复制代码
import MapView from '@arcgis/core/views/MapView';
  let map = new Map();
  const view: any = new MapView({
    container: 'viewDiv',
    map: map,
    zoom: 4
  });

3、设置地图中心点、通过地图服务创建基础图层

ini 复制代码
view.when(() => {
    let pt = new Point({
        x: -3385.861498285485,
        y: -4869.908083566152,
        spatialReference: view.spatialReference
    });
    // 定位到中心点
    view.goTo({
        center: pt,
        zoom: 2
});
//基础图层
let layerUrl = 'http://xxx.xxx.xxx.xxx/arcgis/rest/services/BaseMap/MapServer'; //地图服务URL
let layer = new TileLayer({ url: layerUrl, title: 'baseMap' });
mapLayers.value = layer;
map.layers.add(layer);

地图增加marker点

根据预先配置的测试点,通过Graphic对象包装point点,最终添加到图层上。

typescript 复制代码
//撒点
const renderPoint = () => {
  let pointGraphicArr: any = [];
  pointList.forEach((item: any) => {
    // First create a point geometry
    let point = {
      type: 'point', // autocasts as new Point()
      longitude: item.COORDX,
      latitude: item.COORDY,
      spatialReference: myMapView.spatialReference
    };


    //点样式,(可设置图片,或者自定义颜色的marker,参考symbol)
    let markerSymbol = {
      // type: 'picture-marker',
      // url: img,
      // width: 5,
      // height: 5
      type: 'simple-marker',
      color: [226, 119, 40]
    };

    // 创建点的属性
    let attributes = {
      Name: item.ADDRESS,
      Owner: item.TASKID
    };

    // Create a graphic and add the geometry and symbol to it
    let pointGraphic = new Graphic({
      geometry: point,
      symbol: markerSymbol,
      attributes: attributes
    });

    pointGraphicArr.push(pointGraphic);
  });
  pointGraphics = pointGraphicArr;

  //自定义渲染popup
  setTimeout(() => {
    renderPopup();
  }, 500);

  return pointGraphics;
}

撒点上图

ini 复制代码
view.graphics.addMany(renderPoint());

绘制多变形

与绘制marker点类似,将polyline对象添加到Graphic中,最后都通过view.graphics.addMany添加到地图图层上。具体代码实现如下:

ini 复制代码
//多边形折线
const rendPolyline = () => {
  const polyline = {
    //线的坐标信息
    type: 'polyline', // autocasts as new Polyline()
    paths: [
      [-4466.80859375, -8273.7109375],
      [-3475.872802734375, -6549.30810546875],
      [-4307.0634765625, -5647.63525390625],
      [-4466.80859375, -8273.7109375]
    ],
    spatialReference: myMapView.spatialReference
  };
  const lineSymbol = {
    //线的样式
    type: 'simple-line',
    color: [226, 119, 40],
    width: 2
  };
  const lineAtt = {
    //线的属性
    Name: 'Keystone Pipeline',
    Owner: 'TransCanada',
    Length: '3,456 km'
  };
  const polylineGraphic = new Graphic({
    //创建线对象并且绑定属性以及弹出框信息
    geometry: polyline,
    symbol: lineSymbol,
    attributes: lineAtt
  });

  return [polylineGraphic];
}

绘制多边形覆盖物

可自定义覆盖面的样式,包括背景颜色,边框等属性。

ini 复制代码
//绘制多边形覆盖层面
const rendPolygon = () => {
  const rings = [
    [-4226.57763671875, -10710.984375],
    [-5061.92724609375, -8761.8974609375],
    [-5428.50244140625, -10374.7802734375]
  ];

  const polygon = {
    //面的坐标信息
    type: 'polygon',
    rings: rings,
    spatialReference: myMapView.spatialReference
  };
  const fillSymbol = {
    //面的样式
    type: 'simple-fill',
    color: [227, 139, 79, 0.8],
    outline: {
      // autocasts as new SimpleLineSymbol()
      color: [255, 255, 255],
      width: 1
    }
  };
  const polygonGraphic = new Graphic({
    //创建面图斑
    geometry: polygon,
    symbol: fillSymbol
  });
  //数组
  return [polygonGraphic];
}

热力图实现

首先定义热力图render的值,根据不同的权重占比渲染不同的颜色,注意ObjectID必须需要,然后通过FeatureLayer添加到地图图层上,此处根据count作为权重字段。

css 复制代码
//热力图
const rendHeatmap = () => {
  //热力图渲染
  var heatmapRenderer = new HeatmapRenderer({
    //设置渲染器
    field: 'count', //设置的权重字段
    colorStops: [
      { color: 'rgba(0, 255, 150, 0)', ratio: 0 },
      { color: '#32C5E9', ratio: 0.083 },
      { color: '#67E0E3', ratio: 0.166 },
      { color: '#9FE6B8', ratio: 0.249 },
      { color: '#FFDB5C', ratio: 0.332 },
      { color: '#ff9f7f', ratio: 0.415 },
      { color: '#fb7293', ratio: 0.498 },
      { color: '#E062AE', ratio: 0.581 },
      { color: '#E690D1', ratio: 0.664 },
      { color: '#e7bcf3', ratio: 0.747 },
      { color: '#9d96f5', ratio: 0.83 },
      { color: '#8378EA', ratio: 0.913 },
      { color: '#96BFFF', ratio: 1 }
    ],
    radius: 10,
    maxDensity: 0.01625,
    minDensity: 0
  });
  let features: any = [];
  pointList.forEach((item: any, index: number) => {
    features.push({
      geometry: {
        type: 'point',
        x: item.COORDX,
        y: item.COORDY,
        spatialReference: myMapView.spatialReference
      },
      attributes: {
        count: 1,
        ObjectID: index //重要!!!
      }
    });
  });
  const hfields = [    new Field({      name: 'count',      alias: 'count',      type: 'string'    })  ];
  var featureLayer = new FeatureLayer({
    id: '热力图',
    source: features, //点数据集
    title: '热力图',
    objectIdField: 'ObjectID',
    fields: hfields, //权重字段
    renderer: heatmapRenderer
  });
  myMap.add(featureLayer);
}

绘制点、线、面、圈、矩形

原理都是通过监听鼠标事件,依赖Draw对象的到不同的地图操作效果

创建Draw

arduino 复制代码
 //自定义绘制点、线、面
    const draw = new Draw({
      view: view
    });

划线:

ini 复制代码
 var action = draw.create('polyline', {
    mode: 'click'
  });

画多边形面

csharp 复制代码
 var action = draw.create('polygon', {
    mode: 'click' //点击方式加点
  });

画点

csharp 复制代码
var action = draw.create('point', {
    mode: 'click' //点击方式加点
  });

画圆

csharp 复制代码
 var action = draw.create('circle', {
    mode: 'click' //点击方式加点
  });

画矩形

csharp 复制代码
var action = draw.create('rectangle', {
    mode: 'click' //点击方式加点
  });

具体实现请参考源码,此处不一一列出

自定义实现展示多个popup

由于官方的popup弹出层只能展示一个,而且不能自定义html内容,所以通过自定义实现。 通过view.toScreen能够获取到地图上点距离屏幕top、left的距离,因此,只需要将自定义的popup层在地图进行缩放,移动时动态改变popup的位置,就能实现popup跟随地图移动。

ini 复制代码
 <div class="popup-content" v-for="(item, index) in popupData" :key="index"
      :style="{ top: item.y - 24 + 'px', left: item.x - 30 + 'px' }">自定义弹出层</div>

//自定义渲染popup
const renderPopup = () => {
  let popupDataArr: any = [];
  pointGraphics.forEach((item: any) => {
    let screen = myMapView.toScreen(item.geometry);
    popupDataArr.push(screen);
  });
  popupData.value = popupDataArr;
}

view.on('resize', () => {
renderPopup();
});

view.on('drag', () => {
renderPopup();
});
//滚轮事件
view.on('mouse-wheel', () => {
setTimeout(() => {
    renderPopup();
}, 200);
});

最后

由于ArcGIS API for JavaScript 是英文文档,对于英文不好的同学来说实在不友好,example也比较少不够直观,网上相关资料也不多,各位掘友们路过点赞收藏,说不定以后用到呢。源码可直接查看:gitee.com/fcli/arcgis...

相关推荐
GIS程序媛—椰子10 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00116 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端19 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100923 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439133 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt