448 lines
20 KiB
HTML
448 lines
20 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<!-- Use correct character set. -->
|
||
<meta charset="utf-8" />
|
||
<!-- Tell IE to use the latest, best version. -->
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
|
||
<meta
|
||
name="viewport"
|
||
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
|
||
/>
|
||
<title>Learning Cesium!</title>
|
||
<script src="./Build/Cesium/Cesium.js"></script>
|
||
<script src="./js/polylineTrailLinkMaterialProperty.js"></script>
|
||
<script src="./js/PolylineTrailMaterial.js"></script>
|
||
<script src="./js/utils/WallDiffuseMaterialProperty.js"></script>
|
||
|
||
<script src="./data/hubei/hanjiang_up.js"></script>
|
||
<script src="./data/hubei/hanjiang_mid.js"></script>
|
||
<script src="./data/hubei/hanjiang_down.js"></script>
|
||
<style>
|
||
@import url(./Build/Cesium/Widgets/widgets.css);
|
||
html,
|
||
body,
|
||
#app,
|
||
#cesiumContainer {
|
||
width: 100%;
|
||
height: 100%;
|
||
margin: 0;
|
||
padding: 0;
|
||
overflow: hidden;
|
||
}
|
||
</style>
|
||
<!-- 引入样式 -->
|
||
<link rel="stylesheet" href="./js/elementui/index.css" />
|
||
<!-- import Vue before Element -->
|
||
<script src="./js/vue2710.js"></script>
|
||
<!-- import JavaScript -->
|
||
<script src="./js/elementui/index.js"></script>
|
||
</head>
|
||
<body>
|
||
<div id="app">
|
||
<div id="cesiumContainer"></div>
|
||
</div>
|
||
|
||
<script type="module">
|
||
import {cesiumToken,geoserverConfig} from "./js/mapConfig.js"
|
||
Cesium.Ion.defaultAccessToken = cesiumToken;
|
||
new Vue({
|
||
el: "#app",
|
||
data: {
|
||
shanxiFeatures:[],
|
||
hubeiFeatures:[],
|
||
pois: [
|
||
{
|
||
id: "shangyou",
|
||
name: "上游段",
|
||
type: "point",
|
||
icon: "row.png",
|
||
abstract:
|
||
"上游段:汉江上游全场956千米,集水面积95220平方千米,敢流呈东西走向,穿行于秦岭、大巴山之间,沿途峡谷盆地交替,河床多为卵石、砾石与基岩组成,河道比降大。",
|
||
lon: 108.742874,
|
||
lat: 32.648087,
|
||
},
|
||
{
|
||
id: "zhongyou",
|
||
name: "中游段",
|
||
type: "point",
|
||
icon: "row.png",
|
||
abstract:
|
||
"中游段:汉江自丹江口至碾盘山江段,全长223千米,区间集水面积45120平方千米,河道流经丘陵及开阔的河谷盆地,平均比降0.19‰,河床宽浅,水流散乱,有大小江心洲20余个,属游荡型河道。汉江接纳南河和唐白河后,水量、沙量大增,河床时冲时淤,并受两岸山势节点控制,宽窄不一,低水河槽宽约300-400米,洪水期达2-3千米,最宽可达5-6千米。",
|
||
lon: 112.1797,
|
||
lat: 31.9756,
|
||
},
|
||
{
|
||
id: "xiayou",
|
||
name: "下游段",
|
||
type: "point",
|
||
icon: "row.png",
|
||
abstract:
|
||
"下游段:碾盘山以下,汉江进入下游冲积平原,河段全长398千米,区间集水面积18660平方千米,河段平均比降约0.09‰,水流变缓,弯曲系数1.81,属平原蜿蜒性河道。河床多为沙质,两岸筑有堤防紧束。在潜江泽口龙头拐,有汉江分流-东荆河,汛期可分泄汉江部分洪水,最大过水能力为5600立方米/秒,干流自新城以下,河曲发育,素有“曲莫如汉”的说法,而且两岸堤距和河床断面,呈现上宽下窄的特点,所以河床安全泄量,愈近河口愈小,如遇洪水,宜泄不畅,极易溃口成灾。",
|
||
lon: 113.116358,
|
||
lat: 30.493197,
|
||
},
|
||
// {
|
||
// id: "shanxi",
|
||
// name: "陕西省段",
|
||
// type: "point",
|
||
// icon: "row.png",
|
||
// abstract:
|
||
// "陕西省境内的汉江为汉江上游段,因此山地河流发育,支流众多,长度在50千米以上的河流有68条,在100千米以上的有18条。水系分布为不对称树枝状,北岸支流比南岸多而长,河网密度也比南岸大,北岸为1.69千米/平方千米,南岸只有1.52千米/平方千米。",
|
||
// lon: 108.841,
|
||
// lat: 32.581,
|
||
// },
|
||
// {
|
||
// id: "hubei",
|
||
// name: "湖北省段",
|
||
// type: "point",
|
||
// icon: "row.png",
|
||
// abstract:
|
||
// "在湖北省境内,汉江干流经白河县后,自郧西县进入湖北。丹江口以下,干流折向东南,沿途经襄阳市、宜城市、钟祥市、天门市、潜江市、仙桃市、汉川市等县市,最后由武汉市汉口龙王庙汇入长江。干流丹江口以上为上游,河谷狭窄,长约925千米;丹江口至钟祥为中游,河谷较宽,沙滩多,长约270千米;钟祥至汉口为下游,长约382千米,流经江汉平原,两岸筑有堤防,河道蜿蜒曲折逐步缩小,泄洪能力愈下愈小。",
|
||
// lon: 112.196,
|
||
// lat: 31.991,
|
||
// },
|
||
{
|
||
id: "longwangmiao",
|
||
name: "龙王庙",
|
||
type: "point",
|
||
icon: "row2.png",
|
||
abstract:
|
||
"龙王庙:汉江上游全场956千米,集水面积95220平方千米,敢流呈东西走向,穿行于秦岭、大巴山之间,沿途峡谷盆地交替,河床多为卵石、砾石与基岩组成,河道比降大。汉江上游全场956千米,集水面积95220平方千米,敢流呈东西走向,穿行于秦岭、大巴山之间,沿途峡谷盆地交替,河床多为卵石、砾石与基岩组成,河道比降大。",
|
||
lon: 114.285869,
|
||
lat: 30.569577,
|
||
},
|
||
{
|
||
id: "bozhongshan",
|
||
name: "嶓冢山",
|
||
type: "point",
|
||
icon: "row2.png",
|
||
abstract:
|
||
"嶓冢山:汉江上游全场956千米,集水面积95220平方千米,敢流呈东西走向,穿行于秦岭、大巴山之间,沿途峡谷盆地交替,河床多为卵石、砾石与基岩组成,河道比降大。",
|
||
lon: 106.24576,
|
||
lat: 33.07099,
|
||
},
|
||
],
|
||
},
|
||
methods: {
|
||
initViewer() {
|
||
var viewer = new Cesium.Viewer("cesiumContainer", {
|
||
geocoder: false, //位置查找
|
||
homeButton: false, //视图返回初始位置
|
||
sceneModePicker: false, //视角选择器
|
||
baseLayerPicker:false,//底图选择器
|
||
navigationHelpButton: false, //导航帮助按钮
|
||
animation: false, //动画控制器
|
||
creditContainer:document.createElement("div"),//版权显示
|
||
timeline: false, //时间线
|
||
fullscreenButton: false, //全屏控件
|
||
vrButton: false,
|
||
infoBox: false,
|
||
selectionIndicator: false,
|
||
});
|
||
window.viewer = viewer;
|
||
this.viewer = viewer;
|
||
var imageryLayers = viewer.scene.imageryLayers;
|
||
//清除影像图层集合中的图层
|
||
imageryLayers.removeAll();
|
||
// 添加 Mapbox tile provider
|
||
const mapboxAccess =
|
||
"pk.eyJ1IjoicWl1c2hpamllIiwiYSI6ImNsMDNvdDRybDEyc2YzZG9kbWZoY2FuOW0ifQ.4FH-BUupi46Z0zQ-CEm_Ig";
|
||
|
||
var customMapboxIamgery = new Cesium.MapboxStyleImageryProvider({
|
||
// url: "https://api.mapbox.com/styles/v1",
|
||
username: "qiushijie",
|
||
styleId: "clboooor3000714mi15y9j6ba",
|
||
accessToken: mapboxAccess,
|
||
scaleFactor: true,
|
||
});
|
||
imageryLayers.addImageryProvider(customMapboxIamgery);
|
||
|
||
// 调整整体的亮度
|
||
var collection = viewer.scene.postProcessStages;
|
||
var silhouette = collection.add(
|
||
Cesium.PostProcessStageLibrary.createBrightnessStage()
|
||
);
|
||
silhouette.enabled = true;
|
||
silhouette.uniforms.brightness = 0.7;
|
||
|
||
// 将三维球定位到汉江
|
||
viewer.camera.flyTo({
|
||
destination: new Cesium.Cartesian3(
|
||
-2145613.9928089497,
|
||
5801951.317852074,
|
||
3324754.4962660405
|
||
),
|
||
orientation: {
|
||
heading: 0.11000762620081161,
|
||
pitch: -1.0488202798826602 ,
|
||
roll: 6.283126813396368,
|
||
},
|
||
});
|
||
|
||
// 创建自定义数据源,存放动态墙体的Entity
|
||
this.dwSource = new Cesium.CustomDataSource("dynamicWalll");
|
||
this.viewer.dataSources.add(this.dwSource);
|
||
// 创建自定义数据源,存放poi实体
|
||
this.poiSource = new Cesium.CustomDataSource("poiSource");
|
||
this.viewer.dataSources.add(this.poiSource);
|
||
|
||
// 创建primitive集合,存储水系图元对象
|
||
this.riverPrimitives = this.viewer.scene.primitives.add(
|
||
new Cesium.PrimitiveCollection()
|
||
);
|
||
|
||
//
|
||
this.addPoiLayer(this.pois);
|
||
this.addHanRiver();
|
||
this.addDynamicLine(hanjiang_up);
|
||
this.addDynamicLine(hanjiang_mid);
|
||
this.addDynamicLine(hanjiang_down);
|
||
this.addHanjiangWall();
|
||
this.initEvent(viewer);
|
||
},
|
||
initEvent(viewer){
|
||
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
||
handler.setInputAction(function (evt) {
|
||
//捕获椭球体,将笛卡尔二维平面坐标转为椭球体的笛卡尔三维坐标,返回球体表面的点
|
||
var cartesian3 = viewer.camera.pickEllipsoid(evt.position);
|
||
// let cartesian3 = viewer.scene.pickPosition(evt.position);
|
||
if (cartesian3) {
|
||
//将笛卡尔三维坐标转为地图坐标(弧度)
|
||
var cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3);
|
||
//将地图坐标(弧度)转为十进制的度数
|
||
var lat_String = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
|
||
var log_String = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
|
||
var alti_String = (viewer.camera.positionCartographic.height / 1000).toFixed(2);
|
||
console.log(log_String+","+lat_String)
|
||
}
|
||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
||
},
|
||
addHanjiangWall() {
|
||
const url = "./data/hubei/hanjiang.geojson";
|
||
fetch(url)
|
||
.then((res) => res.json())
|
||
.then((result) => {
|
||
result.features.forEach((feature) => {
|
||
this.addWallByFeature(feature)
|
||
});
|
||
});
|
||
},
|
||
addWallByFeature(feature,minimumHeight,maximumHeight){
|
||
let coords = feature.geometry.coordinates[0][0];
|
||
minimumHeight = minimumHeight?Number(minimumHeight):100,
|
||
maximumHeight = maximumHeight?Number(maximumHeight):5000
|
||
this.dwSource.entities.add({
|
||
name: "发光动态墙体",
|
||
wall: {
|
||
positions: Cesium.Cartesian3.fromDegreesArray(coords.flat(2)),
|
||
material: new Cesium.WallDiffuseMaterialProperty({
|
||
color: Cesium.Color.fromBytes(255, 255, 0).withAlpha(0.7),
|
||
duration: 3000,
|
||
}),
|
||
minimumHeights: Array(coords.length).fill(minimumHeight),
|
||
maximumHeights: Array(coords.length).fill(maximumHeight),
|
||
outline: false,
|
||
},
|
||
});
|
||
},
|
||
addDynamicLine(coords){
|
||
// var orangeOutlined = new Cesium.Entity({
|
||
// name: "指定两点的高度,使实体悬浮于椭球表面",
|
||
// polyline: {
|
||
// positions: Cesium.Cartesian3.fromDegreesArray([
|
||
// 108.870317,29.909681,
|
||
// 110.050511,29.912557,
|
||
// 110.071016,32.370220,
|
||
// ]),
|
||
// width: 5,
|
||
// material: new Cesium.PolylineTrailLinkMaterialProperty({
|
||
// color: Cesium.Color.ORANGE,
|
||
// duration:5000
|
||
// }),
|
||
// },
|
||
// });
|
||
// viewer.entities.add(orangeOutlined);
|
||
|
||
const glowingLine = viewer.entities.add({
|
||
name: "Glowing blue line on the surface",
|
||
polyline: {
|
||
positions: Cesium.Cartesian3.fromDegreesArray(coords.flat(2)),
|
||
width: 2,
|
||
// material: new Cesium.PolylineGlowMaterialProperty({
|
||
// glowPower: 0.2,
|
||
// taperPower: 0.5,
|
||
// color: Cesium.Color.CORNFLOWERBLUE,
|
||
// }),
|
||
material: new PolylineTrailMaterial({
|
||
color: Cesium.Color.WHITE,
|
||
duration:2000
|
||
})
|
||
},
|
||
});
|
||
},
|
||
async addHanJiang(){
|
||
const data = await this.getHanShuiData();
|
||
console.log(data)
|
||
},
|
||
addPoiLayer(data) {
|
||
data.forEach((item) => {
|
||
this.poiSource.entities.add(this.addPoiBill(item));
|
||
});
|
||
},
|
||
addPoiBill(data) {
|
||
let image = this.createPoiLabel(data.name, data.icon);
|
||
return {
|
||
id: JSON.stringify({ ...data, layer: "poi" }),
|
||
position: Cesium.Cartesian3.fromDegrees(data.lon, data.lat, 0),
|
||
billboard: {
|
||
eyeOffset: new Cesium.Cartesian3(0.0, 1.0, 0.0),
|
||
image: image, // default: undefined
|
||
show: true, // default
|
||
// pixelOffset:new Cesium.Cartesian2(-60, 0),
|
||
width: 120, // default: undefined
|
||
height: 80, // default: undefined
|
||
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
|
||
// 10.0,
|
||
// 30000.0
|
||
// ), //根据到相机的距离确定可见性。
|
||
scaleByDistance: new Cesium.NearFarScalar(10, 1.5, 60000000, 0.0),
|
||
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
|
||
},
|
||
};
|
||
},
|
||
async createPoiLabel(label, icon) {
|
||
// 创建画布对象
|
||
let canvas = document.createElement("canvas");
|
||
let len = label.split("").length,
|
||
width = 120,
|
||
height = 80;
|
||
canvas.width = 17 * len > width ? 17 * len : width;
|
||
canvas.height = height;
|
||
let ctx = canvas.getContext("2d");
|
||
|
||
const url1 = "/images/hanjiang/g1.png";
|
||
const url2 = "/images/hanjiang/" + icon;
|
||
let image1 = await new Cesium.Resource.fetchImage(url1);
|
||
ctx.drawImage(image1, 0, 0, canvas.width, 32); //改变图片大小到120*32
|
||
|
||
ctx.fillStyle = "#CFF8FF";
|
||
ctx.lineHeight = 17;
|
||
ctx.font = '700 17px "fangsong"';
|
||
ctx.textBaseline = "middle";
|
||
ctx.fillText(label, 30, 15);
|
||
|
||
let image2 = await new Cesium.Resource.fetchImage(url2);
|
||
let x = canvas.width / 2 - 16;
|
||
ctx.drawImage(image2, x, 37, 32, 42);
|
||
return canvas;
|
||
},
|
||
async getHanData() {
|
||
const filter = geoserverConfig.getFilter([
|
||
{ field: "layer", value: ["湖北省", "陕西省"] },
|
||
]);
|
||
const url =
|
||
"http://121.33.231.74:5097/geoserver/iot/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=iot%3Ahanjiang&maxFeatures=999&outputFormat=application%2Fjson&FILTER=" +
|
||
filter
|
||
.replaceAll("\n", "")
|
||
.replaceAll(" ", "")
|
||
.replaceAll(" ", "%20");
|
||
return await fetch(url).then((res) => res.json());
|
||
},
|
||
async getHanShuiData() {
|
||
const filter = geoserverConfig.getFilter([
|
||
{ field: "name", value: "汉江(汉水)" },
|
||
]);
|
||
const url =
|
||
"http://121.33.231.74:5097/geoserver/iot/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=iot:hubei_hyd1_4p&maxFeatures=999&outputFormat=application%2Fjson&FILTER=" +
|
||
filter
|
||
.replaceAll("\n", "")
|
||
.replaceAll(" ", "")
|
||
.replaceAll(" ", "%20");
|
||
return await fetch(url).then((res) => res.json());
|
||
},
|
||
async addHanRiver() {
|
||
const result = await this.getHanData();
|
||
result.features.forEach((feature) => {
|
||
this.addWaterFeature(this.riverPrimitives, feature);
|
||
if (feature.properties.layer == "陕西省") {
|
||
this.shanxiFeatures.push(feature);
|
||
} else if (feature.properties.layer == "湖北省" ) {
|
||
this.hubeiFeatures.push(feature);
|
||
}
|
||
});
|
||
},
|
||
addWaterFeature(primitives, feature, riverHeight = 0) {
|
||
let geometryType = feature.geometry.type;
|
||
let coord = feature.geometry.coordinates;
|
||
if (geometryType == "MultiPolygon") {
|
||
coord.forEach((polygon) => {
|
||
let outBoundary = null;
|
||
// if(polygon.length==1){
|
||
outBoundary = new Cesium.PolygonHierarchy(
|
||
Cesium.Cartesian3.fromDegreesArray(polygon[0].flat(2))
|
||
);
|
||
// }
|
||
primitives.add(
|
||
new Cesium.Primitive({
|
||
releaseGeometryInstances: false, //由于Cesium使用primitive加载数据性能考虑,会自动清空原来的geometryInstances
|
||
geometryInstances: new Cesium.GeometryInstance({
|
||
id: feature.properties,
|
||
geometry: new Cesium.PolygonGeometry({
|
||
polygonHierarchy: outBoundary,
|
||
extrudedHeight: riverHeight,
|
||
}),
|
||
attributes: {
|
||
// 通过attributes属性统一指定线段颜色
|
||
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||
new Cesium.Color(1.0, 0, 0, 1.0)
|
||
),
|
||
},
|
||
}),
|
||
asynchronous: false,
|
||
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||
material: new Cesium.Material({
|
||
fabric: {
|
||
type: "Water",
|
||
uniforms: {
|
||
// 水的基本颜色
|
||
baseWaterColor: new Cesium.Color(
|
||
64 / 255.0,
|
||
157 / 255.0,
|
||
253 / 255.0,
|
||
0.5
|
||
),
|
||
// 水法向摄动的法线图
|
||
normalMap:
|
||
"./Build/Cesium/Assets/Textures/waterNormals.jpg",
|
||
// 波纹数量
|
||
frequency: 1000.0,
|
||
// 动画速度
|
||
animationSpeed: 0.02,
|
||
// 振动的幅度
|
||
amplitude: 150,
|
||
// 镜面反射的强度
|
||
specularIntensity: 10,
|
||
},
|
||
},
|
||
}),
|
||
faceForward: true,
|
||
}),
|
||
})
|
||
);
|
||
});
|
||
}
|
||
},
|
||
},
|
||
mounted() {
|
||
this.initViewer();
|
||
},
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|