Skip to content
目录

Geo3DTilesLayer

Geo3DTilesLayer是用来加载3D切片数据的,主要有:

  • 3dtile数据
  • arcgis的i3s服务

注意其在maptalks-gl包里,你需要:

sh
npm i maptalks-gl

项目里使用Geo3DTilesLayer主要就是不断的添加和移除图层,显示和隐藏图层这些

js
const layer = new maptalks.Geo3DTilesLayer("3dtiles", {
    loadingLimit: 3,
    loadingLimitOnInteracting: 3,
    services: [
        {
            url: "http://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
            maximumScreenSpaceError: 16.0,
            heightOffset: -400,
        },
    ],
});
//图层操作
layer.show();
layer.hide();
layer.remove();
layer.addTo(groupgl);
js
import { Circle, ClipOutsideMask, Geo3DTilesLayer } from "maptalks-gl";
const layer = new Geo3DTilesLayer("3dtiles", {
    loadingLimit: 3,
    loadingLimitOnInteracting: 3,
    services: [
        {
            url: "http://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
            maximumScreenSpaceError: 16.0,
            heightOffset: -400,
        },
    ],
});
//图层操作
layer.show();
layer.hide();
layer.remove();
layer.addTo(groupgl);

图层参数

创建图层时有几个参数需要注意下:

名字描述
loadingLimit请求切片的并发数量,默认是没有限制,我们可以配置其为一个合适的值,避免单位时间内大面积的网络请求和数据回到导致卡顿
loadingLimitOnInteracting地图交互过程中切片请求的并发数

服务参数

每个3dtile服务里的参数:

名字描述举例
heightOffset模型海拔的偏移量量,有时加载的数据可能悬浮在半空,这是就可以调节这个参数来使其贴地等-100
scale3dtile整体的缩放参数[1,1,1]
rotation3dtile整体的旋转参数[0,0,0]
coordOffset3dtile整体偏移量参数[0.1,0.1]
maximumScreenSpaceError该值越小,渲染精度越高,项目允许的情况下,该值越大性能越好16

常用方法

  • addService(service) 添加一个新的服务
  • updateService(index,service); 更新一个服务
  • removeService(index) 移除一个服务
  • showService(index) 显示一个服务
  • hideService(index) 隐藏一个服务

Geo3DTilesLayer也是支持offset参数的

Geo3DTilesLayer也可以通过配置offset参数来对其进行坐标纠偏的,用法和TileLayer一样

js
function offset(z) {
    //坐标转换的第三方库 https://github.com/hujiulong/gcoord

    const center = map.getCenter();
    const res = map.getGLRes();
    // 坐标由 WGS84 转为 GCJ02
    const c = gcoord.transform(center.toArray(), gcoord.WGS84, gcoord.AMap);
    const coord = map.coordToPointAtRes(new maptalks.Coordinate(c), res);
    const offset = map.coordToPointAtRes(center, res)._sub(coord);
    return offset.toArray();
}

const layer = new maptalks.Geo3DTilesLayer("3dtiles", {
    loadingLimit: 3,
    loadingLimitOnInteracting: 3,
    offset,
    services: [
        {
            url: "http://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
            maximumScreenSpaceError: 16.0,
            heightOffset: -400,
        },
    ],
});

Geo3DTilesLayer图层怎样设置蒙层(Mask)?

Markdown 官方教程

maptalks-gl 包里提供了 ClipOutsideMask 类,其基于Polygon的,用法和Polygon一样,只需要创建一个 ClipOutsideMask 然后将其设置为Geo3DTilesLayer的Mask即可

WARNING

注意其在maptalks-gl包里,你需要:

sh
npm i maptalks-gl

这里我只是以圆的边上的点集合来构造下Polygon的坐标方便测试,实际业务将坐标点换成你自己的业务数据,一般都是行政边界

js
const circle = new maptalks.Circle(
    [108.95938550816857, 34.219794047869385],
    100,
);
//获取圆边上的坐标集合测试
const coordinates = circle.getShell();

//ClipOutsideMask 是Polygon的子类,使用方式和Polygon一样
const mask = new maptalks.ClipOutsideMask([coordinates]);

const layer = new maptalks.Geo3DTilesLayer("3dtiles", {
    services: [
        {
            url: "https://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
            maximumScreenSpaceError: 16.0,
            heightOffset: -400,
        },
    ],
});
layer.once("loadtileset", (e) => {
    //设置layer mask
    layer.setMask(mask);
    const extent = layer.getExtent(e.index);
    map.fitExtent(extent, 0, {
        animation: false,
    });
});

如果你喜欢ESM的方式那就是:

js
import { Circle, ClipOutsideMask, Geo3DTilesLayer } from "maptalks-gl";

const circle = new Circle([108.95938550816857, 34.219794047869385], 100);
//获取圆边上的坐标集合测试
const coordinates = circle.getShell();

//ClipOutsideMask 是Polygon的子类,使用方式和Polygon一样
const mask = new ClipOutsideMask([coordinates]);

const layer = new Geo3DTilesLayer("3dtiles", {
    services: [
        {
            url: "https://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
            maximumScreenSpaceError: 16.0,
            heightOffset: -400,
        },
    ],
});
layer.once("loadtileset", (e) => {
    //设置layer mask
    layer.setMask(mask);
    const extent = layer.getExtent(e.index);
    map.fitExtent(extent, 0, {
        animation: false,
    });
});

常见问题

纹理解压的问题

3dtile的数据一般都是进行纹理压缩的,如果你的程序报类似的错误,那么你需要引入纹理解压插件

  • CDN引入
html
<script
    type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/maptalks-gl/dist/maptalks-gl.min.js"
></script>
<script
    type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/@maptalks/transcoders.draco/dist/transcoders.draco.js"
></script>
<script
    type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/@maptalks/transcoders.crn/dist/transcoders.crn.js"
></script>
<script
    type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/@maptalks/transcoders.ktx2/dist/transcoders.ktx2.js"
></script>
  • ESM

安装:

npm search result

sh
npm i maptalks-gl
npm i @maptalks/transcoders.draco
npm i @maptalks/transcoders.crn
npm i @maptalks/transcoders.ktx2

使用:

js
import { Geo3DTilesLayer, Map } from "maptalks-gl";
import "@maptalks/transcoders.draco";
import "@maptalks/transcoders.crn";
import "@maptalks/transcoders.ktx2";
// ....

ColorMask等事件不能正常响应

考虑到性能问题Geo3DTilesLayer的事件交互(geometryEvents)默认是关闭的,所以如果Geo3DTilesLayer无法响应 事件,创建图层是配置 geometryEvents开启即可

js
const layer = new Geo3DTilesLayer("3dtiles", {
    geometryEvents: true,
    services: [
        {
            url: "https://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
            maximumScreenSpaceError: 16.0,
            heightOffset: -400,
        },
    ],
});
//or
// const layer = new Geo3DTilesLayer("3dtiles", {
//     services: [
//         {
//             url: "https://resource.dvgis.cn/data/3dtiles/dayanta/tileset.json",
//             maximumScreenSpaceError: 16.0,
//             heightOffset: -400,
//         },
//     ],
// });
// layer.options.geometryEvents=true;

This document is generated by mdpress