使用arcgisApi版本 4.11
效果图:
思路:
<1>. 距离和面积测量用到的算法,是由arcgis api提供的类库 "esri/geometry/geometryEngine" 中的geodesicLength()和geodesicArea()
<2>. 调用arcgis api 提供的Draw绘图工具,绘制线和面,在绘制的时候,有一个监听事件一直在监听鼠标操作
<3>.添加graphics到view上
具体方法的代码如下:
需要引入模块的有:
require(['esri/Map',
'esri/Basemap',
'esri/config',
'esri/views/MapView',
'esri/layers/WebTileLayer',
'esri/layers/support/TileInfo',
'dojo/on',
'dojo/dom',
'esri/views/draw/Draw',
'esri/Graphic',
'esri/geometry/geometryEngine',
'esri/geometry/Point',
'esri/geometry/Polyline',
'esri/geometry/Polygon',
'esri/symbols/TextSymbol',
'esri/layers/GraphicsLayer',
'dojo/domReady!'],
function(Map,BaseMap,esriConfig,MapView,WebTileLayer,TileInfo,on,dom,
Draw,Graphic,GeometryEngine,Point,Polyline,Polygon,TextSymbol,
GraphicsLayer){}
)
1. 添加画线button 和画面button 的点击事件,点击按钮后,首先创建Draw对象,然后创建线Action,再绘制的过程中监听绘制的那几个操作,并时刻调用一个方法,也就是下面的createPolyline方法,然后我们就可以在再这个方法中写接下来的实现量测的所有代码了。当然,还可以为每个操作(节点添加、删除、undo、redo等分别添加调用方法,然后写你想实现效果的代码就可以了),这个具体的解释大家可以看官网api
on(dom.byId("btnDrawLine"),"click",function(){
const draw = new Draw({
view: view
});
view.graphics.removeAll();
const action = draw.create("polyline");
view.focus();
action.on(
[
"vertex-add",
"vertex-remove",
"cursor-update",
"redo",
"undo",
"draw-complete"
],
createPolyline
);
});
on(dom.byId("btnDrawPolygon"),"click",function(){
const draw = new Draw({
view: view
});
// view.graphics.removeAll();
const action = draw.create("polygon");
view.focus();
action.on(
[
"vertex-add",
"vertex-remove",
"cursor-update",
"redo",
"undo"
"draw-complete"
],
createPolygon
);
});
2. 实现线量测
function createPolyline(event) {
var vertices = event.vertices;
var symbol={
type:"simple-marker",
color:[255,255,255],
size:6,
outline: {
color: [ 255, 0, 0 ],
width: 1.5 // points
}
};
view.graphics.removeAll();
var graphics=new Graphic({
geometry:new Polyline({
paths: vertices,
spatialReference: view.spatialReference
}),
symbol: {
type: "simple-line", // autocasts as new SimpleFillSymbol
color: [255,116,3],
width: 2,
cap: "round",
join: "round"
}
});
view.graphics.add(graphics);
var firsttextSymbol = {
type: "text",
color: "white",
haloColor: "black",
haloSize: "10px",
text: "起点",
xoffset: '10px',
yoffset: '10px',
font: {
size: 12,
family: "sans-serif",
weight: "bold"
}
};
var firstpoint={
type:"point",
longitude:vertices[0][0],
latitude:vertices[0][1]
};
var firstTextGraphics=new Graphic({
geometry:firstpoint,
symbol: firsttextSymbol
});
var firstGraphics=new Graphic({
geometry:firstpoint,
symbol: symbol
});
view.graphics.add(firstTextGraphics);
view.graphics.add(firstGraphics);
//
var path=[];
var arr1=[];
arr1.push(vertices[0][0]);
arr1.push(vertices[0][1]);
path.push(arr1);
for (let i = 1; i <vertices.length ; i++) {
var point={
type:"point",
longitude:vertices[i][0],
latitude:vertices[i][1]
};
var arr=[];
arr.push(vertices[i][0]);
arr.push(vertices[i][1]);
path.push(arr);
var line = new Polyline({
hasZ: false,
hasM: true,
paths: path,
spatialReference: view.spatialReference
});
var dislen;
var unit;
if(view.scale>5000) {
dislen = GeometryEngine.geodesicLength(line, 'kilometers');
unit="千米";
}else {
dislen = GeometryEngine.geodesicLength(line, 'meters');
unit="米";
}
var textSymbol = {
type: "text",
color: "white",
haloColor: "black",
haloSize: "5px",
text: Math.abs(Math.round(dislen*100)/100)+unit,
xoffset: '20px',
yoffset: '20px',
font: {
size: 12,
family: "sans-serif",
weight: "bold"
}
};
var textGraphics=new Graphic({
geometry:point,
symbol: textSymbol
});
var Graphics=new Graphic({
geometry:point,
symbol: symbol
});
view.graphics.add(textGraphics);
view.graphics.add(Graphics);
}
}
3.实现面量测
function createPolygon(event) {
var vertices = event.vertices;
var symbol={
type:"simple-marker",
color:[255,255,255],
size:6,
outline: {
color: [ 255, 0, 0 ],
width: 1.5 // points
}
};
var fillSymbol = {
type: "simple-fill", // autocasts as new SimpleFillSymbol()
color: [3, 255, 240, 0.1],
outline: {
// autocasts as new SimpleLineSymbol()
color: [255,116,3],
width: 2
}
};
var polygon=new Polygon({
rings: vertices
});
view.graphics.removeAll();
var graphics=new Graphic({
geometry:polygon,
symbol: fillSymbol
});
view.graphics.add(graphics);
var center = polygon.centroid;
var area=0;
var unit;
if(view.scale>5000) {
area = GeometryEngine.geodesicArea(graphics.geometry,'square-kilometers');
unit="平方千米";
}else {
area = GeometryEngine.geodesicArea(graphics.geometry,'square-meters');
unit="平方米";
}
for (let i = 0; i <vertices.length ; i++) {
var point={
type:"point",
longitude:vertices[i][0],
latitude:vertices[i][1]
};
var pointGraphics=new Graphic({
geometry:point,
symbol: symbol
});
view.graphics.add(pointGraphics);
}
var pointcenter={
type:"point",
longitude:center.longitude,
latitude:center.latitude
};
var textSymbol = {
type: "text",
color: "white",
haloColor: "black",
haloSize: "5px",
text:Math.abs(Math.round(area*100)/100)+unit,
font: {
size: 12,
family: "sans-serif",
weight: "bold"
}
};
var textGraphics=new Graphic({
geometry:pointcenter,
symbol: textSymbol
});
view.graphics.add(textGraphics);
}
本文介绍使用ArcGIS API 4.11进行地图上的距离和面积测量方法。通过调用Draw工具和esri/geometry/geometryEngine中的geodesicLength()与geodesicArea()函数,实现线和面的绘制及量测。具体步骤包括创建Draw对象、绘制图形、监听鼠标事件并实时更新测量结果。





