Openlayer 调用天地图瓦片服务

本文介绍了一种自定义实现OpenLayers中的TiandituLayer的方法,通过继承OpenLayers.Layer.Grid并调整参数,实现了从天地图获取不同层级的地图瓦片。文中详细展示了关键代码及如何在项目中引入并使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文关键代码引用自以下博客:

http://www.3sren.com/bbs/home.php?mod=space&uid=189&do=blog&id=5026
我在此基础上根据实际应用加以定制:

OpenLayers.Layer.TiandituLayer = OpenLayers.Class(OpenLayers.Layer.Grid, {

    mapType: null,
    mirrorUrls: null,
    topLevel: null,
    bottomLevel: null,

    topLevelIndex: 0,
    bottomLevelIndex: 20,
    topTileFromX: -180,
    topTileFromY: 90,
    topTileToX: 180,
    topTileToY: -270,

    isBaseLayer: true,

    initialize: function (name,options) {

        options.topLevel = options.topLevel ? options.topLevel : this.topLevelIndex;
        options.bottomLevel = options.bottomLevel ? options.bottomLevel : this.bottomLevelIndex;
        options.maxResolution = this.getResolutionForLevel(options.topLevel);
        options.minResolution = this.getResolutionForLevel(options.bottomLevel);

        var newArguments = [name, {}, {}, options];
        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
    },

    clone: function (obj) {

        if (obj == null) {
            obj = new OpenLayers.Layer.TDTLayer(this.name, this.url, this.options);
        }

        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);

        return obj;
    },

    getURL: function (bounds) {
        var level = this.getLevelForResolution(this.map.getResolution()); 
        var coef = 360 / Math.pow(2, level); 
        var x_num = this.topTileFromX < this.topTileToX ? Math.round((bounds.left - this.topTileFromX) / coef) : Math.round((this.topTileFromX - bounds.right) / coef);
        var y_num = this.topTileFromY < this.topTileToY ? Math.round((bounds.bottom - this.topTileFromY) / coef) : Math.round((this.topTileFromY - bounds.top) / coef);
		
		switch(level){
			case 8:
				url="http://tile6.tianditu.com/DataServer?T=tdt_vip_img_2_10_120627";
				break
			case 9:
				url="http://tile5.tianditu.com/DataServer?T=tdt_vip_img_2_10_120627";
				break
			case 10:
				url="http://tile5.tianditu.com/DataServer?T=tdt_vip_img_2_10_120627";
				break
			case 11:
				url:"http://tile1.tianditu.com/DataServer?T=E11N";
				break
			case 12:
				url="http://tile6.tianditu.com/DataServer?T=E12N";
				break
			case 13:
				url="http://tile3.tianditu.com/DataServer?T=E13N";
				break
			case 14:
				url="http://tile2.tianditu.com/DataServer?T=E14N";
				break
			case 15:
				url="http://tile5.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd"
				break
			case 16:
				url="http://tile2.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd";
				break
			case 17:
				url="http://tile1.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd";
				break
			case 18:
				url="http://tile0.tianditu.com/DataServer?T=tdt_vip_img_120627_dyd";
				break
		}

        return this.getFullRequestString({ T: null, X: x_num, Y: y_num, L: level }, url);
    },
    selectUrl: function (a, b) { return b[a % b.length] },
    getLevelForResolution: function (res) {
        var ratio = this.getMaxResolution() / res;
        if (ratio < 1) return 0;
        for (var level = 0; ratio / 2 >= 1; )
        { level++; ratio /= 2; }
        return level;
    },
    getResolutionForLevel: function (level) {
        return 360 / 256 / Math.pow(2, level);
    },
    getMaxResolution: function () {
        return this.getResolutionForLevel(this.topLevelIndex)
    },
    getMinResolution: function () {
        return this.getResolutionForLevel(this.bottomLevelIndex)
    },
    addTile: function (bounds, position) {
        var url = this.getURL(bounds);
        return new OpenLayers.Tile.Image(this, position, bounds, url, this.tileSize);
    },

    CLASS_NAME: "OpenLayers.Layer.TiandituLayer"
});
使用非常简单,首先要引用这个js文件,然后:

var map=new OpenLayers.Map("mapDiv");
var tianditu=new OpenLayers.Layer.TiandituLayer(
		"tianditu",
		{
		    topLevel:8,
		    bottomLevel:18
		}
	);
map.addLayers([tianditu]);
完成,不过,如果天地图的服务有变动的话,还需要根据实际改动


转载于:https://my.oschina.net/LinBandit/blog/84862

### 天地图3D地形与地址API对接教程 #### 1. 基本概念 天地图的三维地名服务和地形服务可以通过 Cesium 开源三维地球 API 和其扩展插件来实现。此功能依赖于特定版本的 Cesium(如 cesium1.52、1.58 或 1.63.1),并需配合天地图服务接口完成配置[^1]。 #### 2. 技术准备 为了成功集成天地图的3D地形与地址服务,开发者需要具备以下条件: - 安装指定版本的 Cesium 库。 - 配置好天地图的地图服务密钥。 - 熟悉 JavaScript 及其框架(如果使用 Vue.js,则还需掌握该框架的相关知识)[^3]。 #### 3. 实现步骤详解 以下是通过 Cesium 将天地图3D地形与地址进行对接的核心代码示例: ```javascript // 初始化Cesium Viewer对象 var viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider : Cesium.createWorldTerrain() }); // 加载天地图瓦片服务作为底图 viewer.imageryLayers.addImageryProvider( new Cesium.WebMapTileServiceImageryProvider({ url: 'http://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=您的密钥', layer: 'vec', style: 'default', format: 'image/jpeg', tileMatrixSetID: 'w' }) ); // 添加天地图地形服务 viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ url: 'https://data.marsgis.com/terrain/tianditu/' }); ``` 上述代码实现了以下几个目标: - 创建了一个基于 Cesium 的三维视图容器 `cesiumContainer`。 - 设置了世界范围内的高程数据支持。 - 调用天地图的标准矢量瓦片服务作为基础地图层。 - 启用了天地图的地形服务以增强三维效果。 #### 4. 地址解析与位置标注 对于地址到坐标的转换操作,可调用天地图提供的地理编码服务。具体方法如下所示: ```javascript function geocodeAddress(address, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', `https://api.tianditu.gov.cn/geocoder?postStr={"keyWord":"${encodeURIComponent(address)}","type":0,"get_poi":false,"level":9}&tk=您的密钥`, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { var response = JSON.parse(xhr.responseText); if (response && response.data && response.data.lonlat) { const position = Cesium.Cartesian3.fromDegrees(response.data.lonlat.split(',')[0], response.data.lonlat.split(',')[1]); // 在地图上标记位置 viewer.entities.add({ position: position, point: { pixelSize: 10, color: Cesium.Color.RED } }); viewer.zoomTo(viewer.entities); // 缩放至实体 if (callback) { callback(position); } } else { console.error('无法获取坐标'); } } }; xhr.send(null); } geocodeAddress('北京市海淀区中关村大街', function (position) { console.log('已找到位置:', position); }); ``` 这段脚本的功能在于接收输入的地名字符串,并将其转化为经纬度形式以便在三维场景中标记出来[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值