ArcGis绘制多边形这里没有用官方提供的api,官方提供的api是鼠标点击打点然后大于三个点位实时绘面,这种绘制多边形的方式在pc端体验感较佳,但在移动端会差点意思,所以这里提供了另一种绘制多边形的思路以供各位看官参考。
先上效果图
这里在地图创建完毕后监听地图点击并且发布一个全局eventBus(vuex同理)
mapView.on("click", (event) => {
// 获取点击地图时的点
const pt = {
type: 'point',
x: event.mapPoint.x,
y: event.mapPoint.y,
latitude:event.mapPoint.latitude,
longitude:event.mapPoint.longitude,
spatialReference: mapView.spatialReference // 几何图形的空间参照
}
// 事件总线 点
this.$eventBus.$emit('addSpot',pt);
});
复制代码
在点击绘制多边形后订阅这个全局eventBus,并push进你的点位数组
this.$eventBus.$on('addSpot',data =>{
data.id = `point_${this.spotArray.length + 1}`;
this.spotArray.push(data)
})
复制代码
watch监听你的点位数组,数组长度增加执行点点连线的方法
watch:{
// 监听点位数组,变化时执行点点连线方法
spotData(val, oldVal){
if (val.length > oldVal.length){
if (this.addSpotShow){
this.spotConnect();
}
}
}
}
复制代码
在点点连线的方法里判断下点位数组的长度,如果点位只有一个不执行画线,执行绘点;
// 点点测距 连线
spotConnect(){
let point_id = this.spotArray.length; // 点id
if (this.spotArray.length === 1){ // 画地打第一个点时 点图形
let spot = new this.gisGz.Graphic({ // 图形是现实世界地理现象的矢量表示。它可以包含几何图形、符号和属性
attributes: `point_${point_id}`,
geometry: this.spotArray[0], // 定义图形位置的几何图形
symbol: { // 图形符号
type: "simple-marker",
color: [255, 255, 255, 0.8],
size: 15,
text: point_id,
outline: {color: [255, 255, 255, 0]},
},
})
this.sketchViewModel.add(spot); // 绘制层添加当前几何图形
// 点位文字说明
let lengthSymbol = {
type: "text",
color: [50, 50, 50, 1],
font: { size: 10 },
text: "起点",
xoffset: 0,
yoffset: -20,
haloColor: [255, 255, 255, 1],
haloSize: 1,
}
let curPos = new this.gisGz.Point(this.spotArray[0].x, this.spotArray[0].y, this.mapView.spatialReference);
let g = new this.gisGz.Graphic(curPos, lengthSymbol);
g.attributes = `point_${point_id}`;
this.rangingTextLayer.add(g); // 测距文字层,添加 起点 文字
}
if (this.spotArray.length >= 2){
// 实例化长度单位
let params = new this.gisGz.LengthsParameters();
// 计算多边形周长的长度单位
params.lengthUnit = this.gisGz.GeometryService.UNIT_KILOMETER;
// 定义几何的计算类型
params.calculationType = "preserveShape";
let one = this.spotArray[this.spotArray.length - 2]; // 上一个点信息
let two = this.spotArray[this.spotArray.length - 1]; // 当前点信息
let polyline = new this.gisGz.Polyline( // 线信息,起始点,空间参照物
[
[one.x, one.y],
[two.x, two.y],
],
this.mapView.spatialReference
)
// 要计算其长度的折线数组
params.polylines = [polyline];
this.geometryKz.lengths(params).then((distance) => {
let les = distance.lengths[0] * 1;
let dis = 0;
// 小于一公里单位为米
if (les < 1) {
dis = Math.round(les * 1000) + "米";
} else {
dis = les.toFixed(2) + "千米";
}
// 点图形
let spot = new this.gisGz.Graphic({ // 图形是现实世界地理现象的矢量表示。它可以包含几何图形、符号和属性
attributes: `point_${point_id}`,
geometry: two, // 定义图形位置的几何图形
symbol: { // 图形符号
type: "simple-marker",
color: [255, 255, 255, 0.8],
size: 15,
text: point_id,
outline: {color: [255, 255, 255, 0]},
},
})
this.sketchViewModel.add(spot); // 绘制层添加当前几何图形
let textSymbol = {
type: "text",
geometry: two,
color: [50, 50, 50, 1],
font: { size: 10, },
text: dis, // 距离
xoffset: 0,
yoffset: -20,
haloColor: [255, 255, 255, 1],
haloSize: 1,
};
let curPos = new this.gisGz.Point(two.x, two.y, this.mapView.spatialReference)
let g = new this.gisGz.Graphic(curPos, textSymbol);
g.attributes = `point_${point_id}`;
this.rangingTextLayer.add(g); // 测距文字层
});
}
// 绘线
if (this.spotArray.length > 1) {
let one = this.spotArray[this.spotArray.length - 2]; // 上一个点信息
let two = this.spotArray[this.spotArray.length - 1]; // 当前点信息
// 传入两个点 点点绘线
this.connectLine(one, two);
}
},
复制代码
如果大于等于两个点就获取点位数组里最后一个点以及它的前一个点,写一个公共的连线方法,把获取到的两个点传给这个方法
// 点点绘线
connectLine(lineOne,lineTwo){
let polyline_id = this.lineArray.length + 1; // 画线 线id
let line = { // 线信息
id: `polyline_${polyline_id}`,
type: "polyline",
paths: [
[lineOne.x, lineOne.y],
[lineTwo.x, lineTwo.y],
],
spatialReference: this.mapView.spatialReference, // 当前线空间参照
};
let l = new this.gisGz.Graphic({
attributes: `polyline_${polyline_id}`,
geometry: line,
symbol: {
type: "simple-line",
color: [236, 183, 103, 1],
width: 2,
style: "solid",
},
});
this.sketchViewModel.add(l); // 绘制层添加当前几何图形
this.lineArray.push(line); // push进线数组
},
复制代码
中心打点你只需要获取你的地图mapView,然后取它的中心点信息并将其push进点位数组
// 打点层添加点位,根据页面中心点 需要拖动底图进行打点
obtainMapSpot(){
const spot = { // 定义图形位置的几何图形 点信息
id: `point_${this.spotArray.length + 1}`,
type: "point",
x: this.mapView.center.x,
y: this.mapView.center.y,
spatialReference: this.mapView.spatialReference, // 几何图形的空间参照
};
// 将中心点位push进点位数组
this.spotArray.push(spot);
},
复制代码
完成绘制其实就是绘制图形,用ArcGis api将所有点位传给polygon,完成绘制
// 完成绘制封闭图形 绘面
closeModel(){
// 绘制点位小于3 return
if (this.spotArray <= 3){
return
}
let one = this.spotArray[0]; // 第一个点信息
let two = this.spotArray[this.spotArray.length - 1]; // 最后一个点信息
// 传入两个点 点点绘线
this.connectLine(one, two);
let rings = [];
this.spotArray.forEach((item) => { // 获取所有点的图形位置
rings.push([item.x, item.y]);
});
rings.push(rings[0]);
rings.reverse(); // 颠倒数组
let polygon = {
type: "polygon",
rings,
spatialReference: this.mapView.spatialReference, // 定义视图、图层或任务参数的空间参考
};
let p = new this.gisGz.Graphic({
attributes: "remove",
geometry: polygon,
symbol: {
type: "simple-fill",
// color: [236, 183, 103, 0.5],
style: "solid",
outline: {
// color: [236, 183, 103, 1],
width: 1,
},
},
});
// 将坐标转换为地理坐标
let Wgs84Geometry = this.gisGz.webMercatorUtils.webMercatorToGeographic(p.geometry);
// 测试、测量和分析两个或多个 2D 几何之间的空间关系
let Area = this.gisGz.geometryEngine.geodesicArea( Wgs84Geometry, "square-meters" );
// 计算 亩 面积
let Areas = Math.abs(Number(((Area + Area / 2) / 1000).toFixed(2)));
let lengthSymbol = new this.gisGz.TextSymbol({
color: new this.gisGz.Color([255, 255, 255, 1]),
haloColor: new this.gisGz.Color([0, 0, 0, 1]),
haloSize: 1,
font: {
size: 12,
fontWeight: "bold",
},
});
lengthSymbol.text = Areas + "亩";
let t = new this.gisGz.Point( p.geometry.extent.center, this.mapView.spatialReference );
let g = new this.gisGz.Graphic({ attributes: "mianji", geometry: t, symbol: lengthSymbol, });
this.textLayer.add(g); // 文字层
this.sketchViewModel.add(p); // 绘制层
// 清除缓存的撤销点位
this.revokeArray = [];
// 关闭画地按钮禁用
this.addSpotShow = false;
this.spotArray = []; // 清空点位数组
this.$eventBus.$off('addSpot'); // 清除事件订阅
})
},
复制代码