前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ArcGIS JS API 4.16实现三维场景中在天地图底图上加载2000坐标系的倾斜摄影数据

ArcGIS JS API 4.16实现三维场景中在天地图底图上加载2000坐标系的倾斜摄影数据

作者头像
X北辰北
发布2022-02-22 16:00:50
3.1K0
发布2022-02-22 16:00:50
举报
文章被收录于专栏:ArcGIS JS API开发ArcGIS JS API开发

本文主要介绍下如何在国家天地图的底图上面使用ArcGIS JS API 4.16加载2000坐标系的倾斜摄影数据。

所需数据

  • 国家天地图官网数据服务作为底图
  • 自己发布的GCS 2000地理坐标系的倾斜摄影数据服务,对应wkid为4490
  • ArcGIS JS API 4.16 最新版

操作步骤

1、利用esri/layers/BaseTileLayer这个JS API模块扩展出来一个天地图的图层类,具体代码如下:

代码语言:javascript
复制
let TdtLayer = BaseTileLayer.createSubclass({
    properties: {
        urlTemplate: null,
        tint: {
            value: null,
            type: Color,
        },
        subDomains: null,
    },
    getTileUrl: function (level, row, col) {
        return this.urlTemplate
            .replace('{level}', level)
            .replace('{col}', col)
            .replace('{row}', row)
            .replace(
                '{subDomain}',
                this.subDomains[Math.round(Math.random() * (this.subDomains.length - 1))],
            );
    },
    fetchTile: function (level, row, col, options) {
        let url = this.getTileUrl(level + 1, row, col);
        return esriRequest(url, {
            responseType: 'image',
            //新增下面两句,解决乱片问题
            allowImageDataAccess: true,
            signal: options.signal,
        }).then(
            function (response) {
                let image = response.data;
                let width = this.tileInfo.size[0];
                let height = this.tileInfo.size[0];
                let canvas = document.createElement('canvas');
                let context = canvas.getContext('2d');
                canvas.width = width;
                canvas.height = height;
                if (this.tint) {
                    context.fillStyle = this.tint.toCss();
                    context.fillRect(0, 0, width, height);
                    context.globalCompositeOperation = 'difference';
                }
                context.drawImage(image, 0, 0, width, height);
                return canvas;
            }.bind(this),
        );
    },
});

2、因为国家天地图官网的切片服务用的切片方案是国家天地图切片方案,ArcGIS JS API虽然从4.12版本开始支持三维场景中加载2000坐标系服务,但是2000坐标系的切片服务目前仅支持ArcGIS Pro内置的切片方案,所以我们还需要定义一套切片规则来进行两个切片方案的转换,如下:

代码语言:javascript
复制
//定义瓦片结构
let tileInfo = new TileInfo({
    //"dpi": 90.71428571428571,
    dpi: 96,
    rows: 256,
    cols: 256,
    compressionQuality: 0,
    origin: {
        x: -180,
        y: 90,
    },
    spatialReference: {
        wkid: 4490,
    },
    lods: [
        { level: 0, resolution: 0.703125, scale: 295829355.454566 },
        { level: 1, resolution: 0.3515625, scale: 147914677.727283 },
        { level: 2, resolution: 0.17578125, scale: 73957338.863641 },
        { level: 3, resolution: 0.087890625, scale: 36978669.431821 },
        { level: 4, resolution: 0.0439453125, scale: 18489334.71591 },
        { level: 5, resolution: 0.02197265625, scale: 9244667.357955 },
        { level: 6, resolution: 0.010986328125, scale: 4622333.678978 },
        { level: 7, resolution: 0.0054931640625, scale: 2311166.839489 },
        { level: 8, resolution: 0.00274658203125, scale: 1155583.419744 },
        { level: 9, resolution: 0.001373291015625, scale: 577791.709872 },
        { level: 10, resolution: 0.0006866455078125, scale: 288895.854936 },
        { level: 11, resolution: 0.00034332275390625, scale: 144447.927468 },
        { level: 12, resolution: 0.000171661376953125, scale: 72223.963734 },
        { level: 13, resolution: 8.58306884765625e-5, scale: 36111.981867 },
        { level: 14, resolution: 4.291534423828125e-5, scale: 18055.990934 },
        { level: 15, resolution: 2.1457672119140625e-5, scale: 9027.995467 },
        { level: 16, resolution: 1.0728836059570313e-5, scale: 4513.997733 },
        { level: 17, resolution: 5.3644180297851563e-6, scale: 2256.998867 },
        { level: 18, resolution: 0.000002682209014892578, scale: 1128.499433 },
    ],
});

3、接下来,实例化天地图服务图层作为三维场景的底图,然后添加我们2000坐标系的倾斜摄影数据即可,代码和最终效果如下:

代码语言:javascript
复制
let tiledLayer = new TdtLayer({
    urlTemplate:
        'http://{subDomain}.tianditu.com/vec_c/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&LAYER=vec&STYLE=default&FORMAT=tiles&TILEMATRIXSET=c&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=申请的密钥',
    subDomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
    tileInfo: tileInfo,
});
let tdtzjLayer = new TdtLayer({
    urlTemplate:
        'http://{subDomain}.tianditu.com/cva_c/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&LAYER=cva&STYLE=default&FORMAT=tiles&TILEMATRIXSET=c&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=申请的密钥',
    subDomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
    tileInfo: tileInfo,
});
let map = new Map({
    spatialReference: {
        wkid: 4490,
    },
    basemap: {
        baseLayers: [tiledLayer],
        referenceLayers: [tdtzjLayer],
    },
});
let mapView = new SceneView({
    container: 'mainView',
    spatialReference: {
        wkid: 4490,
    },
    map: map,
    center: {
        x: 117,
        y: 39,
        spatialReference: {
            wkid: 4490,
        },
    },
});
let layer01 = new IntegratedMeshLayer({
    url: 'http://www.arcgisonline.cn/server/rest/services/Hosted/Production_4/SceneServer',
    //copyright: "VRICON"
});
mapView.map.add(layer01);
img
img
img
img

4、完整代码如下:

代码语言:javascript
复制
//4.16 加载天地图并添加倾斜摄影数据
_initSceneView416 = () => {
    const _self = this;
    const options = {
        url: 'https://js.arcgis.com/4.16/init.js',
        css: 'https://js.arcgis.com/4.16/esri/themes/light/main.css',
    };
    loadModules(
        [
            'esri/Color',
            'esri/request',
            'esri/layers/BaseTileLayer',
            'esri/Map',
            'esri/views/SceneView',
            'esri/layers/support/TileInfo',
            'esri/layers/IntegratedMeshLayer',
        ],
        options,
    )
        .then(([Color, esriRequest, BaseTileLayer, Map, SceneView, TileInfo, IntegratedMeshLayer]) => {
            let TdtLayer = BaseTileLayer.createSubclass({
                properties: {
                    urlTemplate: null,
                    tint: {
                        value: null,
                        type: Color,
                    },
                    subDomains: null,
                },
                getTileUrl: function (level, row, col) {
                    return this.urlTemplate
                        .replace('{level}', level)
                        .replace('{col}', col)
                        .replace('{row}', row)
                        .replace(
                            '{subDomain}',
                            this.subDomains[Math.round(Math.random() * (this.subDomains.length - 1))],
                        );
                },
                fetchTile: function (level, row, col, options) {
                    let url = this.getTileUrl(level + 1, row, col);
                    return esriRequest(url, {
                        responseType: 'image',
                        //新增下面两句,解决乱片问题
                        allowImageDataAccess: true,
                        signal: options.signal,
                    }).then(
                        function (response) {
                            let image = response.data;
                            let width = this.tileInfo.size[0];
                            let height = this.tileInfo.size[0];
                            let canvas = document.createElement('canvas');
                            let context = canvas.getContext('2d');
                            canvas.width = width;
                            canvas.height = height;
                            if (this.tint) {
                                context.fillStyle = this.tint.toCss();
                                context.fillRect(0, 0, width, height);
                                context.globalCompositeOperation = 'difference';
                            }
                            context.drawImage(image, 0, 0, width, height);
                            return canvas;
                        }.bind(this),
                    );
                },
            });
            //定义瓦片结构
            let tileInfo = new TileInfo({
                //"dpi": 90.71428571428571,
                dpi: 96,
                rows: 256,
                cols: 256,
                compressionQuality: 0,
                origin: {
                    x: -180,
                    y: 90,
                },
                spatialReference: {
                    wkid: 4490,
                },
                lods: [
                    { level: 0, resolution: 0.703125, scale: 295829355.454566 },
                    { level: 1, resolution: 0.3515625, scale: 147914677.727283 },
                    { level: 2, resolution: 0.17578125, scale: 73957338.863641 },
                    { level: 3, resolution: 0.087890625, scale: 36978669.431821 },
                    { level: 4, resolution: 0.0439453125, scale: 18489334.71591 },
                    { level: 5, resolution: 0.02197265625, scale: 9244667.357955 },
                    { level: 6, resolution: 0.010986328125, scale: 4622333.678978 },
                    { level: 7, resolution: 0.0054931640625, scale: 2311166.839489 },
                    { level: 8, resolution: 0.00274658203125, scale: 1155583.419744 },
                    { level: 9, resolution: 0.001373291015625, scale: 577791.709872 },
                    { level: 10, resolution: 0.0006866455078125, scale: 288895.854936 },
                    { level: 11, resolution: 0.00034332275390625, scale: 144447.927468 },
                    { level: 12, resolution: 0.000171661376953125, scale: 72223.963734 },
                    { level: 13, resolution: 8.58306884765625e-5, scale: 36111.981867 },
                    { level: 14, resolution: 4.291534423828125e-5, scale: 18055.990934 },
                    { level: 15, resolution: 2.1457672119140625e-5, scale: 9027.995467 },
                    { level: 16, resolution: 1.0728836059570313e-5, scale: 4513.997733 },
                    { level: 17, resolution: 5.3644180297851563e-6, scale: 2256.998867 },
                    { level: 18, resolution: 0.000002682209014892578, scale: 1128.499433 },
                ],
            });
            let tiledLayer = new TdtLayer({
                urlTemplate:
                    'http://{subDomain}.tianditu.com/vec_c/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&LAYER=vec&STYLE=default&FORMAT=tiles&TILEMATRIXSET=c&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=ac0daf56728bbb77d9514ba3df69bcd3',
                subDomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
                tileInfo: tileInfo,
            });
            let tdtzjLayer = new TdtLayer({
                urlTemplate:
                    'http://{subDomain}.tianditu.com/cva_c/wmts?SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&LAYER=cva&STYLE=default&FORMAT=tiles&TILEMATRIXSET=c&TILEMATRIX={level}&TILEROW={row}&TILECOL={col}&tk=ac0daf56728bbb77d9514ba3df69bcd3',
                subDomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
                tileInfo: tileInfo,
            });
            let map = new Map({
                spatialReference: {
                    wkid: 4490,
                },
                basemap: {
                    baseLayers: [tiledLayer],
                    referenceLayers: [tdtzjLayer],
                },
            });
            let mapView = new SceneView({
                container: 'mainView',
                spatialReference: {
                    wkid: 4490,
                },
                map: map,
                center: {
                    x: 117,
                    y: 39,
                    spatialReference: {
                        wkid: 4490,
                    },
                },
            });
            let layer01 = new IntegratedMeshLayer({
                url: 'http://www.arcgisonline.cn/server/rest/services/Hosted/Production_4/SceneServer',
                //copyright: "VRICON"
            });
            mapView.map.add(layer01);
        })
        .catch((err) => {
            console.log('三维场景实例化失败:', err);
        });
};
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 所需数据
  • 操作步骤
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档