maptalks 开发GIS地图(42)maptalks.three.35- custom-rgbimage-terrain
开发 地图 Custom GIS 42
2023-09-11 14:21:35 时间
1. 可以说,这是我一直想要的效果之一,
另外一个cesium 和 UE 一起搞得那个。
2. 数据使用的是 ./data/west-lake-area.geojson
3. 扩展类
1 class Terrain extends maptalks.BaseObject { 2 constructor(extent, options, material, layer) { 3 options = maptalks.Util.extend({}, OPTIONS, options, { layer, extent }); 4 const { texture, image, altitude, imageHeight, imageWidth, factor, filterIndex } = options; 5 if (!image) { 6 console.error('not find image'); 7 } 8 if (!(extent instanceof maptalks.Extent)) { 9 extent = new maptalks.Extent(extent); 10 } 11 const { xmin, ymin, xmax, ymax } = extent; 12 const coords = [ 13 [xmin, ymin], 14 [xmin, ymax], 15 [xmax, ymax], 16 [xmax, ymin] 17 ]; 18 let vxmin = Infinity, vymin = Infinity, vxmax = -Infinity, vymax = -Infinity; 19 coords.forEach(coord => { 20 const v = layer.coordinateToVector3(coord); 21 const { x, y } = v; 22 vxmin = Math.min(x, vxmin); 23 vymin = Math.min(y, vymin); 24 vxmax = Math.max(x, vxmax); 25 vymax = Math.max(y, vymax); 26 }); 27 const w = Math.abs(vxmax - vxmin), h = Math.abs(vymax - vymin); 28 const rgbImg = generateImage(image), img = generateImage(texture); 29 const geometry = new THREE.PlaneBufferGeometry(w, h, imageWidth - 1, imageHeight - 1); 30 super(); 31 this._initOptions(options); 32 this._createMesh(geometry, material); 33 const z = layer.distanceToVector3(altitude, altitude).x; 34 const v = layer.coordinateToVector3(extent.getCenter(), z); 35 this.getObject3d().position.copy(v); 36 material.transparent = true; 37 if (rgbImg) { 38 material.opacity = 0; 39 rgbImg.onload = () => { 40 const width = imageWidth, height = imageHeight; 41 const imgdata = getRGBData(rgbImg, width, height); 42 let idx = 0; 43 let maxZ = -Infinity; 44 //rgb to height https://docs.mapbox.com/help/troubleshooting/access-elevation-data/ 45 for (let i = 0, len = imgdata.length; i < len; i += 4) { 46 const R = imgdata[i], G = imgdata[i + 1], B = imgdata[i + 2]; 47 const height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1); 48 const z = layer.distanceToVector3(height, height).x * factor; 49 geometry.attributes.position.array[idx * 3 + 2] = z; 50 maxZ = Math.max(z, maxZ); 51 idx++; 52 } 53 this.getOptions().maxZ = maxZ; 54 geometry.attributes.position.needsUpdate = true; 55 if (filterIndex) { 56 const _filterIndex = []; 57 const index = geometry.getIndex().array; 58 const position = geometry.attributes.position.array; 59 const z = maxZ / 15; 60 for (let i = 0, len = index.length; i < len; i += 3) { 61 const a = index[i]; 62 const b = index[i + 1]; 63 const c = index[i + 2]; 64 const z1 = position[a * 3 + 2]; 65 const z2 = position[b * 3 + 2]; 66 const z3 = position[c * 3 + 2]; 67 if (z1 > z || z2 > z || z3 > z) { 68 _filterIndex.push(a, b, c); 69 } 70 } 71 geometry.setIndex(new THREE.Uint32BufferAttribute(_filterIndex, 1)); 72 } 73 if (img) { 74 textureLoader.load(img.src, (texture) => { 75 material.map = texture; 76 material.opacity = 1; 77 material.needsUpdate = true; 78 this.fire('load'); 79 }); 80 } else { 81 material.opacity = 1; 82 } 83 }; 84 rgbImg.onerror = function () { 85 console.error(`not load ${rgbImg.src}`); 86 }; 87 } 88 } 89 }
4. 获取数据,并进行数据处理。
1 fetch('./data/west-lake-area.geojson').then(res => res.json()).then(geojson => { 2 const polygons = maptalks.GeoJSON.toGeometry(geojson); 3 const polygon = polygons[0]; 4 let extent = polygon.getExtent(); 5 6 const { xmin, ymin, xmax, ymax } = extent; 7 let coords = [ 8 [xmin, ymin], 9 [xmin, ymax], 10 [xmax, ymax], 11 [xmax, ymin] 12 ]; 13 let rectangle = new maptalks.Polygon([coords]); 14 const tiles = cover.tiles(rectangle.toGeoJSON().geometry, { 15 min_zoom: 12, 16 max_zoom: 12 17 }); 18 console.log(tiles); 19 //buffer 20 let minx = Infinity, miny = Infinity, maxx = -Infinity, maxy = -Infinity; 21 tiles.forEach(tile => { 22 const [x, y, z] = tile; 23 const { xmin, ymin, xmax, ymax } = baseLayer._getTileLngLatExtent(x, y, z); 24 minx = Math.min(minx, xmin); 25 maxx = Math.max(maxx, xmax); 26 miny = Math.min(miny, ymin); 27 maxy = Math.max(maxy, ymax); 28 }); 29 extent = new maptalks.Extent(minx, miny, maxx, maxy); 30 coords = [ 31 [minx, miny], 32 [minx, maxy], 33 [maxx, maxy], 34 [maxx, miny] 35 ]; 36 rectangle = new maptalks.Polygon([coords]); 37 // layer.addGeometry(rectangle); 38 generateCanvas(tiles, function ({ image, width, height, texture }) { 39 const terrain = new Terrain(extent, { 40 texture, 41 imageWidth: Math.ceil(width / 1), 42 imageHeight: Math.ceil(height / 1), 43 image, 44 factor: 1.5, 45 filterIndex: true 46 }, material, threeLayer); 47 lines.push(terrain); 48 threeLayer.addMesh(terrain); 49 animation(); 50 initGui(); 51 }); 52 })
5. 页面显示
6. 源码地址
https://github.com/WhatGIS/maptalkMap/tree/main/threelayer/demo
相关文章
- Java自学指南二、后端开发全景图与快速入门
- 《C++ 开发从入门到精通》——第2章 C++的重要特质分析2.1 什么是面向对象(object-oriented)
- 《Web前端开发精品课——HTML5 Canvas开发详解》——第一部分 Canvas基础
- 《Xcode实战开发》——2.11节组织器窗口
- 《树莓派开发实战(第2版)》——1.10 优化性能
- openlayers4 入门开发系列之地图展示篇(附源码下载)
- 【正点原子FPGA连载】 第二十四章 RTC实时时钟LCD显示实验-摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0
- maptalks 开发GIS地图(40)maptalks.three.33- custom-mergedmixin-geometry
- maptalks 开发GIS地图(39)maptalks.three.32- custom-mergedmixin
- maptalks 开发GIS地图(38)maptalks.three.31- custom-linetrip
- maptalks 开发GIS地图(35)maptalks.three.28- custom-grid-height
- maptalks 开发GIS地图(34)maptalks.three.27- custom-grid
- maptalks 开发GIS地图(33)maptalks.three.26- custom-geotiffplan
- maptalks 开发GIS地图(32)maptalks.three.25- custom-flight-path
- maptalks 开发GIS地图(30)maptalks.three.23- custom-electricShield
- maptalks 开发GIS地图(27)maptalks.three.20 - custom-circle
- maptalks 开发GIS地图(22)maptalks.three.15 - custom-animation
- maptalks 开发GIS地图(15)maptalks.three.08 - box
- maptalks 开发GIS地图(11)maptalks.three.04 bar-animation
- maptalks 开发GIS地图(7)maptalks.three.00 介绍
- maptalks 开发GIS地图(6)maptalks 介绍
- maptalks 开发GIS地图(3)maptalks 介绍
- maptalks 开发GIS地图(1)maptalks 介绍