应用场景:在地图上自定义绘制一个范围,查询范围内某图层的数据并展示。
思路:
1. 运用arcgis api 的draw工具中的polygon绘制不规则面图形
2. 建立queryTask查询,将绘制的面图形范围当做查询范围
3. 遍历查询回调函数,将数据展示(展示用vue做了个弹窗)
为了测试方便,代码里所引用的css和js都来自网上链接,地图引用的也是arcgis在线地图,有一定的不稳定性。
直接上代码(复制可直接运行):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- <link href="./ElementV1.3.6/index.css" rel="stylesheet"/> -->
<link href="https://cdn.bootcdn.net/ajax/libs/element-ui/1.3.6/theme-default/index.css" rel="stylesheet">
<link rel="stylesheet" href="https://js.arcgis.com/3.26/esri/css/esri.css">
<style>
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<!-- 绘制工具区域 -->
<div class="drawTool" >
<button class="btn btn-info" id="polygon">面</button>
<button class="btn btn-danger" id="quxiao">停</button>
<button class="btn btn-danger" id="remove">移除<span class="fa fa-close"></span></button>
</div>
<!-- vue弹窗区域 -->
<div id="app">
<template>
<el-dialog title="" custom-class="map-dialog" :visible.sync="visible">
<el-table :data="mapData">
<el-table-column prop="Longitude" label="经度" ></el-table-column>
<el-table-column prop="Latitude" label="纬度" ></el-table-column>
<el-table-column prop="Name" label="名称" ></el-table-column>
</el-table>
</el-dialog>
</template>
</div>
<!-- 地图区域 -->
<div id="map"></div>
</body>
<!-- import Vue before Element -->
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- 注意: arcigs js api 要在最后才引入,不然会报错 -->
<script src="https://js.arcgis.com/3.26/"></script>
<script>
//vue 实例
var vm = new Vue({
el: '#app',
data: function() {
return {
visible: false, //默认隐藏弹窗
//数组mapData里数据以对象形式保存
mapData: [
{
Longitude: '经度',
Latitude: '纬度',
Name: '名称'
}
]
}
}
})
require([
"esri/map",
"esri/layers/ArcGISTiledMapServiceLayer",
"esri/layers/FeatureLayer",
"esri/geometry/Extent",
"esri/tasks/query",
"esri/tasks/QueryTask",
"esri/toolbars/draw",
"esri/symbols/SimpleFillSymbol",
"esri/graphic",
"dojo/domReady!"
], function(
Map,
ArcGISTiledMapServiceLayer,
FeatureLayer,
Extent,
Query,
QueryTask,
Draw,
SimpleFillSymbol,
Graphic
) {
//地图范围
var mapExtent = new Extent({
xmax: 113.799760210539,
xmin: 106.57095767482662,
ymax: 20.459116202966324,
ymin: 18.27952992162579,
spatialReference: {
wkid: 4326
}
})
map = new Map("map", {
extent: mapExtent,
sliderStyle: "small",
logo: false,
});
map.on('load', function () {
map.hideZoomSlider()
map.hidePanArrows()
})
//arcgis 在线切片底图
var myTileLayer = new ArcGISTiledMapServiceLayer("http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer", {
visible: true
});
map.addLayer(myTileLayer)
//测试数据:点图层 arcgis在线点图层
var pointFeatureLayer =new FeatureLayer("//services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Earthquakes_Since_1970/FeatureServer/0", {
mode:FeatureLayer.MODE_SNAPSHOT,
outFields: ["*"]
})
map.addLayer(pointFeatureLayer)
//构造绘制工具
var draw = new Draw(map);
//定义图形样式
draw.fillSymbol = new SimpleFillSymbol();
//激活绘制工具
$(".drawTool button").click(function () {
var tool=null;
switch (this.id){
case "polygon": tool="POLYGON"; break;
case "quxiao": draw.deactivate(); break;
case "remove": map.graphics.clear();break;
}
if(tool !== null){
draw.activate(Draw[tool]); //激活对应的绘制工具
}
})
//监听draw,当绘制完成后,执行将绘制图形添加到地图的方法
draw.on("draw-complete",drawEndEvent);
//绘制图形的方法和查询
function drawEndEvent(evt) {
var evtGeometry = evt.geometry
if (evtGeometry.type === "polygon") {
var symbol = draw.fillSymbol
var graphic = new Graphic(evtGeometry,symbol)
map.graphics.clear() //每次绘制前清空之前绘制的图形范围
vm.mapData.length = 0 //每次绘制自定义范围前都将mapData数据清空
map.graphics.add(graphic)
//建立查询
var queryTask = new QueryTask("//services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Earthquakes_Since_1970/FeatureServer/0")
var query = new Query();
query.returnGeometry = true
query.outFields = ['*']
query.geometry = evtGeometry //查询范围为绘制图形的范围
queryTask.execute(query, showQueryResult)
}
}
//查询结果回调函数
function showQueryResult(res) {
var length = res.features.length
if (length > 0) {
for (var i=0; i<length; i++) {
var name = res.features[i].attributes.Name
var lon = res.features[i].attributes.Longitude
var lat = res.features[i].attributes.Latitude
//将数据赋予对象再放入mapData集合
var dataObj = {
Longitude: lon,
Latitude: lat,
Name: name,
}
vm.mapData.push(dataObj)
}
vm.visible = true //显示弹窗
} else {
alert("查询范围没有目标数据")
}
}
})
</script>
</html>
运行效果: