openlayers开发中遇到的问题

最近做了一个web平台,其中有一个地图服务的模块,包含了一些常见的地图操作和轨迹功能,经讨论最终选择了openlayers4作为地图引擎,这里将开发过程中遇到的问题和解决方案贴出来供大家参考,小弟第一次写博客,有写的不对的地方请指正。

// 创建百度地图的数据源
function createBaiduSource(isSatellite) {
  // 自定义分辨率和瓦片坐标系
  var resolutions = [],
    maxZoom = 18;
  // 计算百度使用的分辨率
  for (var i = 0; i <= maxZoom; i++) {
    resolutions[i] = Math.pow(2, maxZoom - i);
  }
  var tilegrid = new ol.tilegrid.TileGrid({
    origin: [0, 0], // 设置原点坐标
    resolutions: resolutions // 设置分辨率
  });

  return new ol.source.TileImage({
    projection: 'EPSG:3857',
    tileGrid: tilegrid,
    tileUrlFunction: function(tileCoord, pixelRatio, proj) {
      var z = tileCoord[0],
        x = tileCoord[1],
        y = tileCoord[2];
      // 百度瓦片服务url将负数使用M前缀来标识
      if (x < 0) {
        x = 'M' + (-x);
      }
      if (y < 0) {
        y = 'M' + (-y);
      }
      var hash = (x << z) + y,
        len = 5; // [0, 1, 2, 3, 4]
      var index = hash % 5;
      index = index < 0 ? index + 5 : index;
      if (isSatellite) {
        // 卫星地图
        return 'http://shangetu' + index + '.map.bdimg.com/it/u=x=' + x + ';y=' + y + ';z=' + z + ';v=009;type=sate&fm=46&app=webearth2&v=009&udt=20171031'
      } else {
        // url最后的参数p=1时显示路网,p=0时不显示路网
        return 'http://online' + index + '.map.bdimg.com/onlinelabel/?qt=tile&x=' + x + '&y=' + y + '&z=' + z + '&styles=pl&udt=20160426&scaler=1&p=1';
      }
    }
  });
}
// 百度地图的矢量路网数据源
var baiduSource = createBaiduSource();
this.mapLayer = new ol.layer.Tile({
    source: baiduSource
});
this.map = new ol.Map({
      logo: getLogoElement(this.opts),
      controls: ol.control.defaults({
        attribution: this.opts.attribution, //右下角的地图信息控件
        rotate: false, // 指北针控件
        zoom: false // 缩放按钮控件
      }).extend(getControls(this.opts)),
      interactions: ol.interaction.defaults(),
      layers: [
        this.mapLayer,
        this.geoPointLayer,
        this.markerLayer,
        this.lineLayer
      ],
      view: new ol.View({
        center: [104.06, 30.67],
        projection: 'EPSG:4326',
        zoom: this.opts.defaultZoom,
        minZoom: this.opts.minZoom,
        maxZoom: this.opts.mapType == 'baidu' ? this.opts.maxZoom_baidu : this.opts.maxZoom,
        // 边界[minx, miny, maxx, maxy]
        extent: util.isArray(this.opts.extent) && this.opts.extent.length == 4 ? this.opts.extent : [-180, -30, 180, 90]
      }),
      target: this.mapContainer
    });

问题一: 这段代码直接以’EPSG:4326’投影初始化地图,但是某些层级时会出现异常,如图同时出现了两个层级
openlayers开发中遇到的问题_第1张图片

原因: projection参数错误,未正确理解’EPSG:4326’和’EPSG:3857’。
解释:‘EPSG:4326’指的是地理坐标系WGS84,’EPSG:3857’是由google团队推动形成的Web Mercator标准,4326的瓦片大小是512×512,3857是256×256。这里地图源的瓦片大小是256×256,与投影projection参数不匹配,所以出现图层加载异常。对坐标系有兴趣的朋友可以去坐标转换那些事儿查看更详细的介绍
解决方案一 以’EPSG:4326’投影初始化地图,将地图源换成瓦片大小是512×512的资源
解决方案二: 以默认的’EPSG:3857’投影初始化地图,将外部输入的地理坐标先转换成3857坐标,再使用,代码如下:

this.map = new ol.Map({
      logo: getLogoElement(this.opts),
      controls: ol.control.defaults({
        attribution: this.opts.attribution, //右下角的地图信息控件
        rotate: false, // 指北针控件
        zoom: false // 缩放按钮控件
      }).extend(getControls(this.opts)),
      interactions: ol.interaction.defaults(),
      layers: [
        this.mapLayer,
        this.geoPointLayer,
        this.markerLayer,
        this.lineLayer
      ],
      view: new ol.View({
        center: ol.proj.transform([104.06584974378, 30.65754338153], 'EPSG:4326', 'EPSG:3857'),
        // projection: 'EPSG:3857',
        zoom: this.opts.defaultZoom,
        minZoom: this.opts.minZoom,
        maxZoom: this.opts.mapType == 'baidu' ? this.opts.maxZoom_baidu : this.opts.maxZoom,
        // 边界[minx, miny, maxx, maxy]
        extent: (() => {
          if(util.isArray(this.opts.extent) && this.opts.extent.length == 4){
            return ol.proj.transformExtent(this.opts.extent, 'EPSG:4326', 'EPSG:3857');
          }else{
            return this.opts.defaultExtent;
          }
        })()
      }),
      target: this.mapContainer
    });

问题二: 百度地图坐标加载偏移。经验证,地图源换成谷歌、高德地图瓦片后,定位点通过坐标系转换(从WGS84到GCJ02),百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系,均能正常显示,但是地图源换成百度地图后,定位点坐标发生偏移。尝试过多种方法,其中有一种自定义了百度投影,仍偏移几百米。路过的大神若有可行的解决方案,望告知,不胜感激!

问题三: 项目发布时,将开发版ol-debug.js切换成发布版ol.js后,ol.js报错,定位到的原因是:ol.geom.GeometryLayout未定义。不清楚是发布版ol.js的bug还是其他什么原因,网上也没有找到相关的说明。
解决方案: 手动定义ol.geom.GeometryLayout

ol.geom.GeometryLayout = {
    XY: 'XY',
    XYZ: 'XYZ',
    XYM: 'XYM',
    XYZM: 'XYZM'
};

你可能感兴趣的:(OpenLayers)