能不能在地图上涂个鸦?我们先看下面这张图:
在上面这张图其实是用点、线和多边形几个图形来绘制出来。在地图上绘制点、线和多边形是基本的功能需求,对于开发者来说,经常会用到,譬如在地图上打点标注、绘制行进的线路、标绘安保区域等等,当然你也可以向我这样很二的来个素描。
言归正卷,要绘制简单的几何图形,就得有工具。目前API里提供了两个工具,一个是简单的,一个是高级的。
- 简单的用SketchViewModel。SketchViewModel简化了将临时几何图形添加到MapView的过程,它节省了大量编写不同几何类型的代码的工作量。要使用SketchViewModel,只需要配置对应的GraphicsLayer,以及点、线、多边形的符号。
- 复杂的用Draw。Draw接口提供针对节点进行编辑的高级功能,特别适合在线的要素编辑,对于传统的地信行业用户来说是一个福音。具体的Draw使用后续再专门讲解。
完整的代码如下:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>二维地图开发-素描点、线与多边形</title>
<link rel="stylesheet" href="http://192.168.1.144/4.6/esri/css/main.css" />
<style>
html,
body,
#mapViewDiv {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color:#8E980F;
}
#sketchToolsDiv {
background: #fff;
position: absolute;
top: 15px;
right: 15px;
padding: 10px;
}
.action-button {
font-size: 16px;
background-color: transparent;
border: 1px solid #D3D3D3;
color: #6e6e6e;
height: 32px;
width: 32px;
text-align: center;
box-shadow: 0 0 1px rgba(0, 0, 0, 0.3);
}
.action-button:hover,
.action-button:focus {
background: #0079c1;
color: #e4e4e4;
}
.active {
background: #0079c1;
color: #e4e4e4;
}
</style>
<script src="http://192.168.1.144/4.6/dojo/dojo.js"></script>
<script>
var myMap, mapView;
require([
"esri/Basemap",
"esri/layers/TileLayer",
"esri/Map",
"esri/views/MapView",
"esri/widgets/Sketch/SketchViewModel",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"dojo/domReady!"
], function (Basemap, TileLayer, Map, MapView, SketchViewModel, Graphic, GraphicsLayer){
// *************************************
// TileLayer接口负责加载ArcGIS Server发布的MapServer缓存切片服务
// http://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer是GeoQ提供的以中国区域为主的缓存切片服务
// TileLayer将作为Basemap对象的一个图层添加到Map对象中。
// *************************************
var layer = new TileLayer({
url: "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer"
});
// *************************************
// Basemap:负责管理所有自定义的基础地图
// 我们可以把所有的基础地图都放在Basemap对象中
// 每个基础地图服务在Basemap对象中都作为一个图层
// *************************************
var customBasemap = new Basemap({
baseLayers: [layer],
title: "基础地图",
id: "gisBasemap"
});
myMap = new Map({
basemap: customBasemap
});
mapView = new MapView({
center: [113.293701, 23.096313], //初始化地图居中时的中心经度、维度
container: "mapViewDiv", //地图展示区域,对应页面上的DIV
map: myMap, //MapView包含Map对象
zoom: 18 //初始显示地图级别
});
// *************************************
// 定义有一个GraphicsLayer,它的职能是作为存储在地图上绘制的点、线、多边形要素.
// GraphicsLayer简称客户端图层,它所保存的要素全部在浏览器端绘制。
// *************************************
sketchGraphicsLayer = new GraphicsLayer();
myMap.add(sketchGraphicsLayer);
//监听地图在加载完成之后,再初始化SketchViewModel
mapView.when(function() {
// *************************************
// SketchViewModel简化了将临时几何图形添加到MapView的过程,它节省了大量编写不同几何类型的代码的工作量。
// 要使用SketchViewModel,只需要配置对应的GraphicsLayer,以及点、线、多边形的符号。
// *************************************
var sketchViewModel = new SketchViewModel({
view: mapView,
sketchayer: sketchGraphicsLayer,
pointSymbol: { //配置点符号
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "circle",
color: "#0413F9",
size: "26px",
outline: { // autocasts as new SimpleLineSymbol()
color: "#DBDBDB",
width: 1 // points
}
},
polylineSymbol: { // symbol used for polylines
type: "simple-line", // autocasts as new SimpleMarkerSymbol()
color: "#9D9C9B",
width: "4",
style: "dash"
},
polygonSymbol: { // symbol used for polygons
type: "simple-fill", // autocasts as new SimpleMarkerSymbol()
color: "#FCA800",
style: "solid",
outline: {
color: "white",
width: 1
}
}
});
//************************************************************
//监听鼠标绘制完成事件
//当绘制完成后,把绘制的图形添加到地图上
//注意,如果是绘制线的话,使用鼠标右键绘制,点击鼠标左键完成绘制
//***********************************************************
sketchViewModel.on("draw-complete", function(evt) {
// add the graphic to the graphics layer
sketchGraphicsLayer.add(evt.graphic);
setActiveButton();
});
// *************************************
// 监听绘制点按钮鼠标点击事件
// 当点击该按钮时,激活sketchViewModel的点绘制功能
// *************************************
var drawPointButton = document.getElementById("pointButton");
drawPointButton.onclick = function() {
// set the sketch to create a point geometry
sketchViewModel.create("point");
setActiveButton(this);
};
// ****************************************
// 监听绘制线按钮鼠标点击事件
// 当点击该按钮时,激活sketchViewModel的线绘制功能
// ****************************************
var drawLineButton = document.getElementById("polylineButton");
drawLineButton.onclick = function() {
// set the sketch to create a polyline geometry
sketchViewModel.create("polyline");
setActiveButton(this);
};
// ***************************************
// 监听绘制多边形按钮鼠标点击事件
// 当点击该按钮时,激活sketchViewModel的多边形绘制功能
// ***************************************
var drawPolygonButton = document.getElementById("polygonButton");
drawPolygonButton.onclick = function() {
// set the sketch to create a polygon geometry
sketchViewModel.create("polygon");
setActiveButton(this);
};
// **************
// 清除在地图上绘制的图形
// **************
document.getElementById("resetBtn").onclick = function() {
sketchGraphicsLayer.removeAll(); //删除GraphicsLayer中的所有要素
sketchViewModel.reset(); //重新恢复sketchViewModel的初始状态
setActiveButton();
};
/**
* 激活按钮,以提醒当前在使用的工具
* @param electedButton
*/
function setActiveButton(selectedButton) {
// focus the view to activate keyboard shortcuts for sketching
mapView.focus();
var elements = document.getElementsByClassName("active");
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
});
});
</script>
</head>
<body>
<div id="mapViewDiv">
</div>
<div id="sketchToolsDiv">
<button class="action-button esri-icon-blank-map-pin" id="pointButton" type="button"
title="绘制点"></button>
<button class="action-button esri-icon-polyline" id="polylineButton" type="button"
title="绘制线"></button>
<button class="action-button esri-icon-polygon" id="polygonButton" type="button"
title="绘制多边形"></button>
<button class="action-button esri-icon-trash" id="resetBtn" type="button" title="清除"></button>
</div>
</body>
</html>
代码量很少,都已经写了注释,所以这里就不过多阐述。需要提醒一点的是API中涉及到的组件按钮,Esri在设计之初都已经提供了相应的CSS样式,譬如下面这个按钮:
<button class="action-button esri-icon-blank-map-pin" id="pointButton" type="button" title="绘制点"></button>
就用到了action-button esri-icon-blank-map-pin这个样式,省去了再去设计按钮样式的麻烦,而且按钮的样式设计的也很美观,对于刚刚接入地图开发的开发者来说,是一个福音,先实现功能,界面还不错,先实现个小目标再说。