React Leaflet Esri 静态切片加载

6 篇文章 0 订阅
6 篇文章 0 订阅
博客介绍了如何利用esri-leaflet库加载非EPSG:3857投影的ArcGIS切片地图,强调了在创建Leaflet地图时需手动设置CRS参数以匹配切片服务的投影信息。文中提供了详细的代码示例,包括静态定义CRS和动态获取服务元数据来创建CRS,并提醒注意引入样式文件防止切片错位。
摘要由CSDN通过智能技术生成

前置说明

  1. 对于通过Arcgis-server直接发布的切片地图(不是图层),esri-leaflet可以对其进行解析与加载
  2. esri-leaflet本质上是对leaflet的layer进行了扩展,使其能够与map对象兼容,但没有对map进行扩展
  3. 因此,对于不是wkid不是3857(即leaflet的map默认投影)的切片地图,在叠加时一定要手工设置map的crs参数
  4. leaflet的map不会因为初始化layer的crs自动调整自己的crs

环境准备

准备切片服务

个人在arcgis-server上发布的切片服务元数据信息(节选)如下:

服务地址为http://localhost:6080/arcgis/rest/services/02_Tky_GDCGK_Tile/MapServer

{
	"singleFusedMapCache": true,
	"tileInfo": {
		"rows": 256,
		"cols": 256,
		"dpi": 96,
		"format": "PNG",
		"compressionQuality": 0,
		"origin": {
			"x": -400,
			"y": 399.9999999999998
		},
		"spatialReference": {
			"wkid": 4490,
			"latestWkid": 4490
		},
		"lods": [
			{
				"level": 0,
				"resolution": 0.00951784402332112,
				"scale": 4000000
			},
			{
				"level": 1,
				"resolution": 0.00475892201166056,
				"scale": 2000000
			},
			{
				"level": 2,
				"resolution": 0.00237946100583028,
				"scale": 1000000
			},
			{
				"level": 3,
				"resolution": 0.00118973050291514,
				"scale": 500000
			},
			{
				"level": 4,
				"resolution": 0.00059486525145757,
				"scale": 250000
			},
			{
				"level": 5,
				"resolution": 0.000297432625728785,
				"scale": 125000
			},
			{
				"level": 6,
				"resolution": 0.00015228550437313792,
				"scale": 64000
			},
			{
				"level": 7,
				"resolution": 0.00007614275218656896,
				"scale": 32000
			},
			{
				"level": 8,
				"resolution": 0.00003807137609328448,
				"scale": 16000
			},
			{
				"level": 9,
				"resolution": 0.00001903568804664224,
				"scale": 8000
			}
		]
	}
	//其他内容省略...
}

安装投影转换包

npm install proj4 proj4leaflet

安装leaflet/esri-leaflet支持包

npm install leaflet esri-leaflet

操作步骤

  1. 定义与切片地图lods层级/原点一致的crs对象
  2. 创建地图并指定目标crs
  3. 创建图层并指定初始化参数
  4. 加载到地图中

实例代码

import React, { useEffect } from 'react';
import L from "leaflet"
import * as esri from "esri-leaflet"
import 'proj4/dist/proj4-src';
import 'proj4leaflet/src/proj4leaflet';
import "../node_modules/leaflet/dist/leaflet.css";

function EsriTileLayer(props) {
    useEffect(() => {
        let CRS_4490 = new L.Proj.CRS("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs", {
            resolutions: [
                0.00951784402332112,
                0.00475892201166056,
                0.00237946100583028,
                0.00118973050291514,
                5.9486525145757E-4,
                2.97432625728785E-4,
                1.5228550437313792E-4,
                7.614275218656896E-5,
                3.807137609328448E-5,
                0.00274658203125,
                0.001373291015625,
                1.903568804664224E-5
            ],
            origin: [-400.0, 399.9999999999998],
        });
        let map = L.map('leaflettilelayer_map', { crs: CRS_4490 }).setView([29.677, 106.914], 4);
        let tileLayer = esri.tiledMapLayer({ url: 'http://localhost:6080/arcgis/rest/services/02_Tky_GDCGK_Tile/MapServer' });
        tileLayer.addTo(map);
    }, [])
    return (
        <div id="leaflettilelayer_map" style={{ width: "100%", height: "800px" }}></div>
    );
}

export default EsriTileLayer;

代码说明

  1. 这里需要定义的是proj4leaflet中的crs,因此必须要有缩放层级和原点信息
  2. crs中的resolutions和origin信息,应该与切片地图的缩放层级保持一致,否则会出现切片行列号计算错误,而找不到切片的问题
  3. 与dynamicMapLayer不一样,tileMapLayer的url是写在构造函数的config对象参数中的,而不是一个单独的函数参数
  4. 这里的url不需要加图层索引号
  5. 一定要引入"leaflet.css"的样式文件,否则切片加载会出现错位的问题

扩展内容

tileMaplayer提供了metadata方法获取当前地图服务的元数据信息,因此可以通过该方法动态的加载当前地图服务的lods和origin信息

function EsriTileLayer2(props) {

    useEffect(() => {
        let layer = esri.tiledMapLayer({ url: "http://localhost:6080/arcgis/rest/services/02_Tky_GDCGK_Tile/MapServer" });
        layer.metadata((error, context) => {
            let { spatialReference, lods, origin } = context.tileInfo
            let current_crs = new L.Proj.CRS(factory.toDefName(spatialReference.wkid), 
                                             factory.toDefStr(spatialReference.wkid), 
                                             factory.parseLods(lods, origin))
            let map = L.map('leaflettilelayer2_map', { crs: current_crs }).setView([29.677, 106.914], 4);
            layer.addTo(map)
        })
    }, [])

    return (
        <div id="leaflettilelayer2_map" style={{ width: "100%", height: "800px" }}></div>
    );
}

export default EsriTileLayer2;

其中factory的各种方法其实就是将context中的内容解析并转换为crs定义所需要的形式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值