zoukankan      html  css  js  c++  java
  • maptalks 开发GIS地图(42)maptalks.three.35- custom-rgbimage-terrain

    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

  • 相关阅读:
    初识Jmeter
    【性能/接口测试】【Jmeter】保存响应内容
    【Java-jxl插件】【Excel文件读写报错】jxl.read.biff.BiffException: Unable to recognize OLE stream
    随机生成九宫格图形密码-实现
    转载:测试人员的挑战
    运行UI自动化脚本报错,和appium server连接出现问题
    Jenkins容器无法执行docker命令
    【接口测试】使用httpClient获取cookies+携带获取的cookies访问get接口
    【Nginx】安装&环境配置
    【PostMan】批量参数化的用法 之 text/csv
  • 原文地址:https://www.cnblogs.com/googlegis/p/14738386.html
Copyright © 2011-2022 走看看