作者:kele
前言
在三维项目开发过程中,通常会涉及到城市规划建模,比如将一块区域压平,在其上方添加各种模型,如果需要添加大量的模型,这个步骤会将相当繁琐,下面将介绍一种压平并自动添加模型的方法。
一、核心思路
1.绘制压平面
2.计算出用于种树的点坐标
3.执行种树
二、事前准备
1.关键接口
倾斜摄影压平
添加模型
2.计算坐标方法
我们通过绘制压平面的极值范围计算出种树坐标,再通过turf.js判断空间范围,只保留在压平面范围内的点
在线库的地址:https://npmcdn.com/@turf/turf/turf.min.js
三、关键代码
<script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
handlerPolygon.drawEvt.addEventListener(function (result) {
handlerPolygon.polygon.show = false;
handlerPolygon.polyline.show = false;
var polygon = result.object;
var positions = polygon.positions;
var flatPoints = []; //压平面点集合
var allLON = []; //用于存储所有点的经度值,便于后续寻找极值
var allLAT = []; //用于存储所有点的纬度值,便于后续寻找极值
var height;
var turfpoly1 = []; //参与turf.js运算的面节点集合需要满足 [[[x,y],[x,y],[x,y],[x,y]...]]
var turfpoly3 = []; //turfpoly1,turfpoly2,turfpoly3 构造适用于turf.js的面坐标
for (var i = 0, j = positions.length; i < j; i++) {
var turfpoly2 = [];
var position = positions[i];
var cartographic = Cesium.Cartographic.fromCartesian(position); //将绘制的点转为经纬度坐标
var lon = Cesium.Math.toDegrees(cartographic.longitude);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
height = cartographic.height;
allLON.push(lon);
allLAT.push(lat);
flatPoints.push(lon); //压平面点集合
flatPoints.push(lat); //压平面点集合
flatPoints.push(height); //压平面点集合
turfpoly2.push(lon);
turfpoly2.push(lat);
turfpoly1.push(turfpoly2);
if (i === positions.length - 1) { //turf.js传入面坐标需要第一个与最后一个相同
turfpoly1.push(turfpoly1[0])
}
}
turfpoly3.push(turfpoly1);
console.log(turfpoly3);
var maxLON = Math.max.apply(null, allLON);
var minLON = Math.min.apply(null, allLON);
var maxLAT = Math.max.apply(null, allLAT);
var minLAT = Math.min.apply(null, allLAT);
var per = (maxLON - minLON) / 20; //经度方向种植数量
var per2 = (maxLAT - minLAT) / 20; //纬度方向种植数量
for (var i = 0; i < 20; i++) { //根据压平面经纬度最值范围构造点
var thisLON = minLON + i * per;
for (var j = 0; j < 20; j++) {
var thisLAT = minLAT + j * per2;
var pt = turf.point([thisLON, thisLAT]); //构造点
var poly = turf.polygon(turfpoly3); //构造面
var cc = turf.booleanPointInPolygon(pt, poly); //判断当前构造点是否在构造面内
var position_a = Cesium.Cartesian3.fromDegrees(parseFloat(thisLON), parseFloat(thisLAT), height+10);
if (cc === true) {
s3mInstanceColc.add(defaultUrl, {
position: position_a,
hpr: new Cesium.HeadingPitchRoll(0, 0, 0),
scale: new Cesium.Cartesian3(1, 1, 1),
});
}
}
}
layer.addFlattenRegion({
position: flatPoints,
name: 'flatten' + Math.random()
});
});