openlayers -----------坐标系篇(小贴士)

openlayers 默认的坐标系的原点在左上角,向上为y轴正方向,向右为x轴正方向。
也就是说,地图投影到一个平面后,平面的左边对应着地球的西边,也是x轴负方向;平面上面对应地图的北面,也是y轴正方向。

但是并不是所有的瓦片地图都采用这样的坐标系,例如百度地图,它是将坐标系原点设为地图视图的中心点,因此坐标是有正负的,负值添加了 'M’ 前缀作为区分。

<div id="baiduMap" style="width: 100%"></div>
<script>
    // 百度地图层
    var baiduMapLayer = new ol.layer.Tile({
        source: new ol.source.XYZ({
            tilePixelRatio: 2,
             // 这里没有直接写url,而是通过tileUrlFunction去处理坐标系原点,再返回url。参数tileCoord为瓦片坐标
            tileUrlFunction: function(tileCoord){ 
                var z = tileCoord[0];
            	var x = tileCoord[1];
        		var y = tileCoord[2];

        			// 计算当前层级下瓦片总数的一半,用于定位整个地图的中心点;瓦片数量=2 * z;z为当前层级;openlayers是以 2的幂次方的速度  来缩放的;
        			var halfTileNum = Math.pow(2, z-1);
       				 // 原点移到中心点后,计算xy方向上新的坐标位置
       				 var baiduX =  x - halfTileNum;
        			var baiduY =  y + halfTileNum;

       				 // 百度瓦片服务url将负数使用M前缀来标识
        			if (baiduX < 0) {
           				 baiduX = 'M' + (-baiduX);
       				 }
      			  if (baiduY < 0) {
           			    baiduY = 'M' + (-baiduY);
      			    }

        			// 返回经过转换后,对应于百度在线瓦片的url
			      return 'http://online2.map.bdimg.com/onlinelabel/?qt=tile&x=' + baiduX + '&y=' + baiduY + '&z=' + z + '&styles=pl&udt=20160321&scaler=2&p=0';
            }
        })
    });

    // 创建地图
  var map = new ol.Map({
        layers: [
            baiduMapLayer
        ],
        view: new ol.View({
            // 设置成都为地图中心
            center: [104.06, 30.67],
            projection: 'EPSG:4326',
            zoom: 4
        }),
        target: 'baiduMap'
  });
</script>```

可以发现,百度地图的坐标系向右为x正方向,向上为y正方向的坐标系,与数学上的笛卡尔坐标系一致。但是上面的代码中心点会有偏差,可能是openlayers 与 百度在线瓦片地图的分辨率对不上导致的,因此我们还需要重新定义分辨率。

```javascript
<div id="baiduMap2" style="width: 100%"></div>
<script>

  // 自定义分辨率和瓦片坐标系
  var resolutions = [];
  var maxZoom = 18;

  // 计算百度使用的分辨率
  for(var i=0; i<=maxZoom; i++){
      resolutions[i] = Math.pow(2, maxZoom-i); //计算每一层的分辨率,存进 resolutions 中
  }
  var tilegrid  = new ol.tilegrid.TileGrid({
      origin: [0,0],    // 设置原点坐标
      resolutions: resolutions    // 设置分辨率
  });

  // 创建百度地图的数据源
  var baiduSource = new ol.source.TileImage({
      projection: 'EPSG:3857',    
      tileGrid: tilegrid,
      tileUrlFunction: function(tileCoord, pixelRatio, proj){
          var z = tileCoord[0];
          var x = tileCoord[1];
          var y = tileCoord[2];

          // 百度瓦片服务url将负数使用M前缀来标识
          if(x<0){
              x = 'M' + (-x);
          }
          if(y<0){
              y = 'M' + (-y);
          }

          return "http://online0.map.bdimg.com/onlinelabel/?qt=tile&x="+x+"&y="+y+"&z="+z+"&styles=pl&udt=20160426&scaler=1&p=0";
      }
  });

    // 百度地图层
    var baiduMapLayer2 = new ol.layer.Tile({
        source: baiduSource
    });

    // 创建地图
  new ol.Map({
        layers: [
            baiduMapLayer2
        ],
        view: new ol.View({
            // 设置成都为地图中心
            center: [104.06, 30.67],
            projection: 'EPSG:4326',
            zoom: 4
        }),
        target: 'baiduMap2'
  });
</script>

上面的代码用到了ol.tilegrid.TileGrid,这个是瓦片网格,在其中定义了坐标原点和每一层的分辨率;需要注意的是,它与笛卡尔坐标系一样,默认情况下,从左向右为x正方向,从下向上为y轴正方向。使用这个类可以重新定义 openlayers 的瓦片地图坐标系。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值