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

所需数据

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

操作步骤

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

                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内置的切片方案,所以我们还需要定义一套切片规则来进行两个切片方案的转换,如下:

                //定义瓦片结构
                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坐标系的倾斜摄影数据即可,代码和最终效果如下:

                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);

4、完整代码如下:

    //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);
            });
    };

猜你喜欢

转载自blog.csdn.net/qq_35117024/article/details/108990344