mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-04 09:14:17 +00:00 
			
		
		
		
	
		
			
	
	
		
			150 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			150 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| 
								 | 
							
								<!--********************************************************************
							 | 
						||
| 
								 | 
							
								* by jiawanlong
							 | 
						||
| 
								 | 
							
								*********************************************************************-->
							 | 
						||
| 
								 | 
							
								<!DOCTYPE html>
							 | 
						||
| 
								 | 
							
								<html>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<head>
							 | 
						||
| 
								 | 
							
								    <meta charset="UTF-8" />
							 | 
						||
| 
								 | 
							
								    <link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
							 | 
						||
| 
								 | 
							
								    <script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
							 | 
						||
| 
								 | 
							
								    <script src="./turf.min.js"></script>
							 | 
						||
| 
								 | 
							
								    <script src="./kriging.js"></script>
							 | 
						||
| 
								 | 
							
								</head>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
							 | 
						||
| 
								 | 
							
								    <div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    <script>
							 | 
						||
| 
								 | 
							
								        window.viewer = new Cesium.Viewer('map', {
							 | 
						||
| 
								 | 
							
								            imageryProvider: false,
							 | 
						||
| 
								 | 
							
								            baseLayerPicker: false,
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        var xyz = new Cesium.UrlTemplateImageryProvider({
							 | 
						||
| 
								 | 
							
								            "credit": "安徽",
							 | 
						||
| 
								 | 
							
								            "url": '///data.mars3d.cn/tile/img/{z}/{x}/{y}.jpg'
							 | 
						||
| 
								 | 
							
								        })
							 | 
						||
| 
								 | 
							
								        viewer.imageryLayers.addImageryProvider(xyz)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const polygonGeojson = turf.polygon([[[110, 30], [110.1, 30], [110.1, 30.1], [110, 30.1], [110, 30]]]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const points = [];
							 | 
						||
| 
								 | 
							
								        const bbox = [110, 30, 110.1, 30.1]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        turf.randomPoint(125, { bbox: bbox }).features.forEach(element => {
							 | 
						||
| 
								 | 
							
								            points.push({
							 | 
						||
| 
								 | 
							
								                lng: element.geometry.coordinates[0],
							 | 
						||
| 
								 | 
							
								                lat: element.geometry.coordinates[1],
							 | 
						||
| 
								 | 
							
								                value: getRandomNum(0, 1000)
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 2. 提取数据
							 | 
						||
| 
								 | 
							
								        const lons = points.map(point => point.lng);
							 | 
						||
| 
								 | 
							
								        const lats = points.map(point => point.lat);
							 | 
						||
| 
								 | 
							
								        const values = points.map(point => point.value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 3. 训练变异函数
							 | 
						||
| 
								 | 
							
								        const variogram = kriging.train(values, lons, lats, 'exponential', 0, 100);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const xMin = bbox[0], yMin = bbox[1], xMax = bbox[2], yMax = bbox[3];
							 | 
						||
| 
								 | 
							
								        const polygons = [[[xMin, yMin], [xMin, yMax], [xMax, yMax], [xMax, yMin]]];
							 | 
						||
| 
								 | 
							
								        const gridWidth = 0.002; // 调整此值!
							 | 
						||
| 
								 | 
							
								        const grid = kriging.grid(polygons, variogram, gridWidth);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 5. 创建并裁剪方块单元
							 | 
						||
| 
								 | 
							
								        const xLim = [grid.xlim[0], grid.xlim[1]];
							 | 
						||
| 
								 | 
							
								        const yLim = [grid.ylim[0], grid.ylim[1]];
							 | 
						||
| 
								 | 
							
								        const features = [];
							 | 
						||
| 
								 | 
							
								        for (let i = 0; i < grid.data.length; i++) {
							 | 
						||
| 
								 | 
							
								            for (let j = 0; j < grid.data[i].length; j++) {
							 | 
						||
| 
								 | 
							
								                const value = grid.data[i][j];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                const x = xLim[0] + i * gridWidth;
							 | 
						||
| 
								 | 
							
								                const y = yLim[0] + j * gridWidth;
							 | 
						||
| 
								 | 
							
								                const cellBbox = [x, y, x + gridWidth, y + gridWidth];
							 | 
						||
| 
								 | 
							
								                const cellPolygon = turf.bboxPolygon(cellBbox);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                const clippedCell = turf.booleanContains(polygonGeojson, cellPolygon);
							 | 
						||
| 
								 | 
							
								                if (clippedCell) {
							 | 
						||
| 
								 | 
							
								                    cellPolygon.properties = { 'value': value };
							 | 
						||
| 
								 | 
							
								                    features.push(turf.feature(cellPolygon.geometry, cellPolygon.properties));
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        let myEntityCollection = new Cesium.CustomDataSource("clickEntityCollection");
							 | 
						||
| 
								 | 
							
								        viewer.dataSources.add(myEntityCollection);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        features.forEach(function (feature) {
							 | 
						||
| 
								 | 
							
								            myEntityCollection.entities.add({
							 | 
						||
| 
								 | 
							
								                polygon: {
							 | 
						||
| 
								 | 
							
								                    extrudedHeight: Number(Number(feature.properties.value)),
							 | 
						||
| 
								 | 
							
								                    hierarchy: Cesium.Cartesian3.fromDegreesArray(feature.geometry.coordinates[0].flat()),
							 | 
						||
| 
								 | 
							
								                    material: Cesium.Color.fromCssColorString(getElevationColor(Number(feature.properties.value))),
							 | 
						||
| 
								 | 
							
								                    outline: false
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        viewer.flyTo(myEntityCollection);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // 高程颜色映射算法
							 | 
						||
| 
								 | 
							
								        function getElevationColor(elevation) {
							 | 
						||
| 
								 | 
							
								            // 确保高程值在0-10000范围内
							 | 
						||
| 
								 | 
							
								            const clampedElevation = Math.max(0, Math.min(10000, elevation));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 定义10个关键高程点的颜色
							 | 
						||
| 
								 | 
							
								            const colorStops = [
							 | 
						||
| 
								 | 
							
								                { value: 0, color: [0, 100, 0] },         // 深绿色 - 海平面
							 | 
						||
| 
								 | 
							
								                { value: 100, color: [34, 139, 34] },    // 森林绿
							 | 
						||
| 
								 | 
							
								                { value: 200, color: [152, 251, 152] },  // 浅绿色
							 | 
						||
| 
								 | 
							
								                { value: 300, color: [240, 230, 140] },  // 卡其色
							 | 
						||
| 
								 | 
							
								                { value: 400, color: [255, 215, 0] },    // 金黄色
							 | 
						||
| 
								 | 
							
								                { value: 500, color: [255, 165, 0] },    // 橙色
							 | 
						||
| 
								 | 
							
								                { value: 600, color: [255, 140, 0] },    // 深橙色
							 | 
						||
| 
								 | 
							
								                { value: 700, color: [255, 99, 71] },    // 番茄红
							 | 
						||
| 
								 | 
							
								                { value: 800, color: [255, 69, 0] },     // 红橙色
							 | 
						||
| 
								 | 
							
								                { value: 900, color: [255, 0, 0] },      // 红色
							 | 
						||
| 
								 | 
							
								                { value: 1000, color: [128, 0, 0] }      // 深红色 - 最高点
							 | 
						||
| 
								 | 
							
								            ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 找到高程值所在的区间
							 | 
						||
| 
								 | 
							
								            for (let i = 0; i < colorStops.length - 1; i++) {
							 | 
						||
| 
								 | 
							
								                const currentStop = colorStops[i];
							 | 
						||
| 
								 | 
							
								                const nextStop = colorStops[i + 1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (clampedElevation >= currentStop.value && clampedElevation <= nextStop.value) {
							 | 
						||
| 
								 | 
							
								                    // 计算在当前区间中的比例 (0-1)
							 | 
						||
| 
								 | 
							
								                    const ratio = (clampedElevation - currentStop.value) /
							 | 
						||
| 
								 | 
							
								                        (nextStop.value - currentStop.value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    // 对RGB三个通道分别进行插值
							 | 
						||
| 
								 | 
							
								                    const r = Math.round(currentStop.color[0] +
							 | 
						||
| 
								 | 
							
								                        ratio * (nextStop.color[0] - currentStop.color[0]));
							 | 
						||
| 
								 | 
							
								                    const g = Math.round(currentStop.color[1] +
							 | 
						||
| 
								 | 
							
								                        ratio * (nextStop.color[1] - currentStop.color[1]));
							 | 
						||
| 
								 | 
							
								                    const b = Math.round(currentStop.color[2] +
							 | 
						||
| 
								 | 
							
								                        ratio * (nextStop.color[2] - currentStop.color[2]));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    // 返回RGB颜色字符串
							 | 
						||
| 
								 | 
							
								                    return `rgb(${r}, ${g}, ${b},0.5)`;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // 如果高程值超出范围,返回最后一个颜色
							 | 
						||
| 
								 | 
							
								            const lastStop = colorStops[colorStops.length - 1];
							 | 
						||
| 
								 | 
							
								            return `rgb(${lastStop.color[0]}, ${lastStop.color[1]}, ${lastStop.color[2]},0.5)`;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        function getRandomNum(Min, Max) {
							 | 
						||
| 
								 | 
							
								            const Range = Max - Min + 1;
							 | 
						||
| 
								 | 
							
								            const Rand = Math.random();
							 | 
						||
| 
								 | 
							
								            return Min + Math.floor(Rand * Range);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    </script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</body>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</html>
							 |