<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'/>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no'/>
<link rel='stylesheet'/>
<script src='http://ua.bigemap.com:30081/bmsdk/bigemap-gl.js/v1.1.0/bigemap-gl.js'></script>
<style>
body {
margin: 0;
padding: 0;
}
#container {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.info{
position: absolute;
top:0;
left: 0;
right: 0;
z-index: 9;
text-align: center;
height: 30px;
line-height: 30px;
color: #909399;
background: #f4f4f5;
}
</style>
<title>part_test</title>
</head>
<body>
<div class="info">
點(diǎn)擊地圖可以獲取當(dāng)前位置的可視域分析(藍(lán)色表示可見,紅色不為可見)
</div>
<div id='container'></div>
<script>
bmgl.Config.HTTP_URL = 'http://ua.bigemap.com:30081/bmsdk/';
var viewer = new bmgl.Viewer('container', {mapId: 'bigemap.dc-tian-w-satellite',requestRenderMode:false,terrainId: 'bigemap.dc-terrain'});
//設(shè)置初始位置
viewer.camera.setView({
destination: bmgl.Cartesian3.fromDegrees(103.59526245619938,30.9814012061604,3837.4144546),
orientation: {"heading":6.282150327905171,"roll":6.279635689524259,"pitch":-0.6993902253931052}
});
//當(dāng)前的視點(diǎn)坐標(biāo)
var startPoint={
lng:103.5898409037154,
lat:31.012823472619534
};
var clickAble=true;
viewer.screenSpaceEventHandler.setInputAction(function (e) {
var ray=viewer.camera.getPickRay(e.position);
var c=viewer.scene.globe.pick(ray,viewer.scene);
if (!clickAble||!bmgl.defined(c))return;
clickAble=false;
setTimeout(()=>{
clickAble=true;
},1000);
c=bmgl.Cartographic.fromCartesian(c);
startPoint.lng=bmgl.Math.toDegrees(c.longitude)
startPoint.lat=bmgl.Math.toDegrees(c.latitude);
drawLine();
},bmgl.ScreenSpaceEventType.LEFT_CLICK);
var pointArr=[];
viewer.scene.globe.depthTestAgainstTerrain=true;
setTimeout(function () {
//1秒后開始畫視角
drawLine();
},1000);
function drawLine() {
pointArr.map(v=>v.remove());
pointArr.length=0;
var viewHeight = 1.5;//視角高度
var cartographicCenter = bmgl.Cartographic.fromDegrees(startPoint.lng, startPoint.lat);
var cartesianCenterH0 = bmgl.Cartesian3.fromRadians(cartographicCenter.longitude, cartographicCenter.latitude);
var cartesianPointH0 = bmgl.Cartesian3.fromDegrees(startPoint.lng+0.02, startPoint.lat+0.01);
var ab = bmgl.Cartesian3.distance(cartesianCenterH0, cartesianPointH0);
var eopt = {};
eopt.semiMinorAxis = ab;
eopt.semiMajorAxis = ab;
eopt.rotation = 0;
eopt.center = cartesianCenterH0;
eopt.granularity = Math.PI / 20;//間隔
var ellipse = computeEllipseEdgePositions(eopt);
for (var i = 0; i < ellipse.outerPositions.length; i += 3) {
//逐條計(jì)算可視域
var cartesian = new bmgl.Cartesian3(ellipse.outerPositions[i], ellipse.outerPositions[i + 1], ellipse.outerPositions[i + 2]);
var cartographic = bmgl.Cartographic.fromCartesian(cartesian);
var deltaRadian = 0.00005 * Math.PI / 180.0;
var cartographicArr = InterpolateLineCartographic(cartographicCenter, cartographic, deltaRadian);
getTerrain(cartographicArr,terrainData=>{
try {
if (terrainData.length > 0) {
var preVisible = true;
var cartesiansLine = [];
var colors = [];
for (var j = 1; j < terrainData.length; j++) {
//逐點(diǎn)計(jì)算可見性
var visible = true;//該點(diǎn)可見性
if (j > 1) {
var cartographicCenterHV = new bmgl.Cartographic(terrainData[0].longitude, terrainData[0].latitude, terrainData[0].height + viewHeight);
//
if (preVisible) {
//
var curPoint = InterpolateIndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
if (curPoint.height >= terrainData[j - 1].height) {
preVisible = true;
visible = true;
} else {
preVisible = false;
visible = false;
}
} else {
//插值到當(dāng)前
var curPointArr = Interpolate2IndexLineHeightCartographic(cartographicCenterHV, terrainData[j], j, j - 1);
for (var k = 0; k < curPointArr.length; k++) {
if (curPointArr[k].height >= terrainData[k].height) {
preVisible = true;
visible = true;
} else {
preVisible = false;
visible = false;
break;
}
}
}
}
var cartesianTemp = bmgl.Cartesian3.fromRadians(terrainData[j].longitude, terrainData[j].latitude, terrainData[j].height + 0.10);
cartesiansLine.push(cartesianTemp);
//繪制點(diǎn)
if (visible) {
colors.push(0);
colors.push(0);
colors.push(1);
colors.push(1);
} else {
colors.push(1);
colors.push(0);
colors.push(0);
colors.push(1);
}
}
//繪制結(jié)果
var pointsKSY = new PrimitivePoints({ 'viewer': viewer, 'Cartesians': cartesiansLine, 'Colors': colors });
pointArr.push(pointsKSY);
} else {
console.log("高程異常!");
}
}catch (e) {
console.log(e);
}
})
}
}
function getTerrain(arr,callback) {
bmgl.sampleTerrainMostDetailed(viewer.terrainProvider,arr).then(data=>{
callback(data);
})
}
/**
* options.semiMinorAxis:短半軸
* options.semiMajorAxis:長(zhǎng)半軸
* options.rotation:旋轉(zhuǎn)角度 弧度
* options.center:中心點(diǎn) 笛卡爾坐標(biāo)
* options.granularity:粒度 弧度
* Returns an array of positions that make up the ellipse.
* @private
*/
function computeEllipseEdgePositions(options) {
var unitPosScratch = new bmgl.Cartesian3();
var eastVecScratch = new bmgl.Cartesian3();
var northVecScratch = new bmgl.Cartesian3();
var scratchCartesian1 = new bmgl.Cartesian3();
var semiMinorAxis = options.semiMinorAxis;
var semiMajorAxis = options.semiMajorAxis;
var rotation = options.rotation;//法線
var center = options.center;
var granularity = options.granularity && (typeof options.granularity === "number") ? options.granularity : (Math.PI / 180.0);// 角度間隔
if (granularity > Math.PI / 12.0) { granularity = Math.PI / 12.0; }//最小分24
if (granularity < Math.PI / 180.0) { granularity = Math.PI / 180.0; }//最大分360
var aSqr = semiMinorAxis * semiMinorAxis;
var bSqr = semiMajorAxis * semiMajorAxis;
var ab = semiMajorAxis * semiMinorAxis;
var mag = bmgl.Cartesian3.magnitude(center);//
var unitPos = bmgl.Cartesian3.normalize(center, unitPosScratch);
var eastVec = bmgl.Cartesian3.cross(bmgl.Cartesian3.UNIT_Z, center, eastVecScratch);
eastVec = bmgl.Cartesian3.normalize(eastVec, eastVec);
var northVec = bmgl.Cartesian3.cross(unitPos, eastVec, northVecScratch);
var numPts = Math.ceil(bmgl.Math.PI*2 / granularity);
var deltaTheta = granularity;
var theta = 0;
var position = scratchCartesian1;
var i;
var outerIndex = 0;
var outerPositions = [];
for (i = 0; i < numPts; i++) {
theta = i * deltaTheta;
position = pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, position);
outerPositions[outerIndex++] = position.x;
outerPositions[outerIndex++] = position.y;
outerPositions[outerIndex++] = position.z;
}
var r = {};
r.numPts = numPts;
r.outerPositions = outerPositions;
return r;
};
/*
線段插值
經(jīng)緯度坐標(biāo)插值
Cartographic start.longitude start.latitude 單位:弧度
return [Cartographic,...]
*/
function InterpolateLineCartographic(start, end, _Delta) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
var result = [];
//開始點(diǎn)
result.push(new bmgl.Cartographic(start.longitude, start.latitude));
var interval = Math.sqrt(Math.pow((end.longitude - start.longitude), 2) + Math.pow((end.latitude - start.latitude), 2));
var delta = _Delta && (typeof _Delta === 'number') ? _Delta : DeltaRadian;
if (interval <= delta) {
//小于最小間隔
result.push(new bmgl.Cartographic(end.longitude, end.latitude));
return result;
} else {
var num = interval / delta;
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
for (var i = 0; i < num; i++) {
var lon = start.longitude + (i + 1) * stepLon;
var lat = start.latitude + (i + 1) * stepLat;
result.push(new bmgl.Cartographic(lon, lat));//與最后一個(gè)點(diǎn)有偏差
}
result.push(new bmgl.Cartographic(end.longitude, end.latitude, end.height));
}
return result;
}
function InterpolateIndexLineHeightCartographic(start, end, num, index) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
//var delta = _Delta && (typeof _Delta === 'number') ? _Delta : DeltaRadian;
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
var stepHeight = (end.height - start.height) / num;
var lon = start.longitude + index * stepLon;
var lat = start.latitude + index * stepLat;
var hieght = start.height + index * stepHeight;
var result = new bmgl.Cartographic(lon, lat, hieght);
return result;
}
/*
線段插值
經(jīng)緯度高程插值
Cartographic start.longitude start.latitude 單位:弧度 start.height 高程單位m
num:分總段數(shù) 傳入數(shù)組長(zhǎng)度-1
index:獲取到第index點(diǎn)的所有插值 0點(diǎn)是開始點(diǎn)
return [Cartographic,...]
*/
function Interpolate2IndexLineHeightCartographic(start, end, num, curIndex) {
if (start && end) { } else { return null; }
if (start.longitude && start.latitude && end.longitude && end.latitude) { } else { return null; }
var result = [];
result.push(new bmgl.Cartographic(start.longitude, start.latitude, start.height));
var stepLon = (end.longitude - start.longitude) / num;
var stepLat = (end.latitude - start.latitude) / num;
var stepHeight = (end.height - start.height) / num;
for (var i = 0; i < curIndex; i++) {
var lon = start.longitude + (i + 1) * stepLon;
var lat = start.latitude + (i + 1) * stepLat;
var hieght = start.height + (i + 1) * stepHeight;
result.push(new bmgl.Cartographic(lon, lat, hieght));
}
//result.push(new bmgl.Cartographic(end.longitude, end.latitude, end.height));
return result;
}
function pointOnEllipsoid(theta, rotation, northVec, eastVec, aSqr, ab, bSqr, mag, unitPos, result) {
var rotAxis = new bmgl.Cartesian3();
var tempVec = new bmgl.Cartesian3();
var unitQuat = new bmgl.Quaternion();
var rotMtx = new bmgl.Matrix3();
var azimuth = theta + rotation;
bmgl.Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis);
bmgl.Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec);
bmgl.Cartesian3.add(rotAxis, tempVec, rotAxis);
var cosThetaSquared = Math.cos(theta);
cosThetaSquared = cosThetaSquared * cosThetaSquared;
var sinThetaSquared = Math.sin(theta);
sinThetaSquared = sinThetaSquared * sinThetaSquared;
var radius = ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared);
var angle = radius / mag;
// Create the quaternion to rotate the position vector to the boundary of the ellipse.
bmgl.Quaternion.fromAxisAngle(rotAxis, angle, unitQuat);
bmgl.Matrix3.fromQuaternion(unitQuat, rotMtx);
bmgl.Matrix3.multiplyByVector(rotMtx, unitPos, result);
bmgl.Cartesian3.normalize(result, result);
bmgl.Cartesian3.multiplyByScalar(result, mag, result);
return result;
}
var PrimitivePoints = (
function () {
var vertexShader;
var fragmentShader;
var geometry;
var appearance;
var viewer;
function _(options) {
viewer = options.viewer;
vertexShader = VSPolylie();
fragmentShader = FSPolyline();
if (options.Cartesians && options.Cartesians.length >= 2) {
var postionsTemp = [];
var colorsTemp = [];
var indicesTesm = [];
if (options.Colors && options.Colors.length === options.Cartesians.length * 4) {
for (var i = 0; i < options.Cartesians.length; i++) {
postionsTemp.push(options.Cartesians[i].x);
postionsTemp.push(options.Cartesians[i].y);
postionsTemp.push(options.Cartesians[i].z);
}
colorsTemp = options.Colors;
} else {
for (var i = 0; i < options.Cartesians.length; i++) {
postionsTemp.push(options.Cartesians[i].x);
postionsTemp.push(options.Cartesians[i].y);
postionsTemp.push(options.Cartesians[i].z);
//
colorsTemp.push(0.0);
colorsTemp.push(0.0);
colorsTemp.push(1.0);
colorsTemp.push(1.0);
}
}
for (var i = 0; i < options.Cartesians.length; i++) {
indicesTesm.push(i);
}
this.positionArr = new Float64Array(postionsTemp);
this.colorArr = new Float32Array(colorsTemp);
this.indiceArr = new Uint16Array(indicesTesm);
} else { // if (options.Cartesians && options.Cartesians.length >= 2) {
var p1 = bmgl.Cartesian3.fromDegrees(0, 0, -10);
var p2 = bmgl.Cartesian3.fromDegrees(0, 0.001, -10);
this.positionArr = new Float64Array([
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z
]);
//默認(rèn)藍(lán)色
this.colorArr = new Float32Array([
0.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 1.0
]);
this.indiceArr = new Uint16Array([0, 1]);
}
geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
appearance = CreateAppearence(fragmentShader, vertexShader);
this.primitive = viewer.scene.primitives.add(new bmgl.Primitive({
geometryInstances: new bmgl.GeometryInstance({
geometry: geometry
}),
appearance: appearance,
asynchronous: false
}));
}
function CreateGeometry(positions, colors, indices) {
return new bmgl.Geometry({
attributes: {
position: new bmgl.GeometryAttribute({
componentDatatype: bmgl.ComponentDatatype.DOUBLE,
componentsPerAttribute: 3,
values: positions
}),
color: new bmgl.GeometryAttribute({
componentDatatype: bmgl.ComponentDatatype.FLOAT,
componentsPerAttribute: 4,
values: colors
})
},
indices: indices,
primitiveType: bmgl.PrimitiveType.POINTS,
boundingSphere: bmgl.BoundingSphere.fromVertices(positions)
});
}
function CreateAppearence(fs, vs) {
return new bmgl.Appearance({
renderState: {
blending: bmgl.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,
depthTest: { enabled: true },
depthMask: true
},
fragmentShaderSource: fs,
vertexShaderSource: vs
});
}
function VSPolylie() {
return "attribute vec3 position3DHigh;\
attribute vec3 position3DLow;\
attribute vec4 color;\
varying vec4 v_color;\
attribute float batchId;\
void main()\
{\
vec4 p = czm_computePosition();\
v_color =color;\
p = czm_modelViewProjectionRelativeToEye * p;\
gl_Position = p;\
gl_PointSize=4.0;\
}\
";
}
function FSPolyline() {
return "varying vec4 v_color;\
void main()\
{\
float d = distance(gl_PointCoord, vec2(0.5,0.5));\
if(d < 0.5){\
gl_FragColor = v_color;\
}else{\
discard;\
}\
}\
";
}
_.prototype.remove = function () {
if (this.primitive != null) {
viewer.scene.primitives.remove(this.primitive);
this.primitive = null;
}
}
_.prototype.updateCartesianPosition = function (cartesians) {
if (this.primitive != null) {
viewer.scene.primitives.remove(this.primitive);
if (cartesians && cartesians.length < 2) { return; }
if (cartesians.length === this.positionArr.length / 3) {
var p1 = cartesians[0];
var p2 = cartesians[1];
this.positionArr = new Float64Array([
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z
]);
geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
} else {
//默認(rèn)藍(lán)色
var postionsTemp = [];
var colorsTemp = [];
var indicesTesm = [];
for (var i = 0; i < cartesians.length; i++) {
postionsTemp.push(cartesians[i].x);
postionsTemp.push(cartesians[i].y);
postionsTemp.push(cartesians[i].z);
colorsTemp.push(0.0);
colorsTemp.push(0.0);
colorsTemp.push(1.0);
colorsTemp.push(1.0);
}
for (var i = 0; i < cartesians.length; i++) {
indicesTesm.push(i);
}
this.positionArr = new Float64Array(postionsTemp);
this.colorArr = new Float32Array(colorsTemp);
this.indiceArr = new Uint16Array(indicesTesm);
geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
appearance = CreateAppearence(fragmentShader, vertexShader);
}
this.primitive = viewer.scene.primitives.add(new bmgl.Primitive({
geometryInstances: new bmgl.GeometryInstance({
geometry: geometry
}),
appearance: appearance,
asynchronous: false
}));
} else { return; }
}
_.prototype.updateCartesianPositionColor = function (cartesians, colors) {
if (colors.length === cartesians.length * 4) { } else { return; }
if (this.primitive != null) {
viewer.scene.primitives.remove(this.primitive);
if (cartesians && cartesians.length < 2) { return; }
if (cartesians.length === this.positionArr.length / 3) {
var p1 = cartesians[0];
var p2 = cartesians[1];
this.positionArr = new Float64Array([
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z
]);
this.colorArr = new Float32Array(colors);
geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
} else {
var postionsTemp = [];
var indicesTesm = [];
for (var i = 0; i < cartesians.length; i++) {
postionsTemp.push(cartesians[i].x);
postionsTemp.push(cartesians[i].y);
postionsTemp.push(cartesians[i].z);
}
for (var i = 0; i < cartesians.length; i++) {
indicesTesm.push(i);
}
this.positionArr = new Float64Array(postionsTemp);
this.colorArr = new Float32Array(colors);
this.indiceArr = new Uint16Array(indicesTesm);
geometry = CreateGeometry(this.positionArr, this.colorArr, this.indiceArr);
appearance = CreateAppearence(fragmentShader, vertexShader);
}
this.primitive = viewer.scene.primitives.add(new bmgl.Primitive({
geometryInstances: new bmgl.GeometryInstance({
geometry: geometry
}),
appearance: appearance,
asynchronous: false
}));
} else { return; }
}
return _;
})();
</script>
</body>
</html>