使用OpenLayers加载离线地图瓦片(天地图标准TMS格式)


地图资源的获取

  关于地图资源的获取,这个可以用一些常见的地图下载器进行下载,然后将地图数据导出为需要格式的瓦片,我这里使用的是太乐地图下载器,下载的是上海市地图(2-18级),导出为标准的TMS瓦片,文导出的文件是这样的,数字代表层级,每个文件夹下都是X方向的瓦片文件夹,每个X方向的瓦片文件夹下是Y方向的瓦片。
在这里插入图片描述

OpenLayers的获取和测试环境

  可以在OpenLayers官网上下载需要的开发包,使用的是build和css文件夹,下面上代码

<!DOCTYPE html>
<html lang="zh-CN">
 <head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  <link rel="stylesheet" href="./css/ol.css" type="text/css" /> 
  <title>二维地图测试</title> 
  <style>
      .myposition
      {
        float:left;
        position:relative;
        bottom: 10px;
        width: 100px;
        height: 10px;
        z-index: 2000;
      }
      .map 
      {
        height: 100%;
        width: 95%;
      }
      .mousePosition
      {
        color:blue;
        font-size: 15px;
        font-family:'微软雅黑';
      }
    </style> 
  <script src="./build/ol.js"></script> 
  <script type="text/javascript">
      window.onload = function () {
            //初始化鼠标位置控件
            var mousePositionControl = new ol.control.MousePosition({
                //样式类名称
                className: 'mousePosition',
                //投影坐标格式,显示小数点后边多少位
                coordinateFormat: ol.coordinate.createStringXY(8),
                //指定投影
                projection: 'EPSG:4326',
                //目标容器
                target:document.getElementById('myposition')
            });
            //标准TMS切片加载方式
        var offlineSource =  new ol.source.XYZ({
            tileUrlFunction: function (coordinate) {
              console.log(coordinate[0],coordinate[1],coordinate[2]);
              var z = coordinate[0];
              var x = coordinate[1];
              var y = Math.pow(2,z-1)+coordinate[2];
              return "file:///D:/mapOutput/TDT_L18_TMS/" + z + "/" + x + "/" + y + ".png";
        },
            maxZoom: 18,
            minZoom: 2,
            projection: 'EPSG:4326'
      });

    var offlineMapLayer = new ol.layer.Tile({
        source: offlineSource
    });

    //调试瓦片图层
    var tileDebugLayer = new ol.layer.Tile({
            source: new ol.source.TileDebug({
              projection: 'EPSG:4326',
              tileGrid: offlineSource.getTileGrid(),
            })
          });
    var center = [121.4659,31.2];
    //创建地图
    var map = new ol.Map({
            view: new ol.View({ 
                center: center,
                projection: 'EPSG:4326',
                zoom: 13
              }),
            controls: ol.control.defaults().extend([mousePositionControl]),
            target: 'map'
          });
    map.addLayer(offlineMapLayer);
    map.addLayer(tileDebugLayer);
  }
    </script> 
 </head> 
 <body> 
  <div id="map" class="map"> 
  </div> 
  <div id="myposition"></div>  
 </body>
</html>

以上是使用本地的图片进行加载,网上也有很多其他的加载方式。值得注意的是由于不同地图提供商的瓦片规则都不太一样,所以使用时不要拘泥于上面的代码,需要找到对应的x,y,z坐标对应规则,刚开始的时候这个瓦片的格式真的搞死我了,也是一点点调出来的,因为跟网上发的完全不一样,如果哪位看到了代码中的错误和遗漏也请不吝赐教。另外注意导出的瓦片的坐标系,常用的有EPSG4326和EPSG3857之分,OpenLayers默认使用的是EPSG3857,一定要设置正确,经纬度信息才会显示正确。

2019.02.21更新:
之前下载的是天地图无偏移格式WGS84坐标系下的离线地图资源是EPSG:4326投影坐标系,算是加载成功了,但最近加载EPSG:3857(web墨卡托投影)的离线地图资源时出现了新的问题,我的地图是可以加载的,但出来的经纬度坐标总是有偏差,后来才发现,source的projection参数没写对。我原来的想法是这里的projection应该写成我的目标投影方式,所以即使我使用的是EPSG:3857投影坐标系的资源,我还是写成了EPSG:4326,但其实这里的projection应该是你使用的资源的投影坐标系。而最终你要显示的坐标投影方式可以在map的view中设置。说的有点绕,下面贴出两段代码供参考:

var sateliteLayerSource = new XYZ({
	tileUrlFunction: function(coordinate) {
		var z = coordinate[0];
		var x = coordinate[1];
		var y =  Math.pow(2, z) + coordinate[2];//EPSG:3857切片规则
		//GCJ-02,火星坐标系
		return 'http://localhost:9310/JDGOOGLE_L19_TMS_QH/' + z + '/' + x + '/' + y + '.png';
	},
	maxZoom: 19,
	minZoom: 0,
	projection: 'EPSG:3857'//注意这里要写成你下载的地图资源使用的投影坐标系
});
var map = new Map({
	view: new View({
		//center: transform(center, 'EPSG:4326','EPSG:3857'),
		//projection: 'EPSG:3857',
		center: center,
		projection: 'EPSG:4326',
		maxZoom: 19,
		minZoom: 0,
		zoom: 16,
	}),
	target: 'map'
});

转载自:https://blog.csdn.net/guimaxingtian/article/details/84880720

You may also like...