Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Baidu layer #3522

Closed
dandv opened this issue Apr 8, 2015 · 38 comments
Closed

Add Baidu layer #3522

dandv opened this issue Apr 8, 2015 · 38 comments
Labels

Comments

@dandv
Copy link

dandv commented Apr 8, 2015

For the Greater China region, a Baidu Map layer would be very helpful.

I've created a Wikipedia page about Baidu Maps and their BD-09 coordinate system.

Baidu has an extensive API with large rate limits. The documentation is in Chinese, but installing the Google Translate extension makes it relatively readable.

So far I've found the API for returning tiles. They're branded with Baidu's logo, but hopefully someone else can pick up from here.

"http://api.map.baidu.com/staticimage?center="
  + lon + "," + lat 
  + "&width=" + width + "&height=" + width + "&zoom=" + zoom;

Result of http://api.map.baidu.com/staticimage?center=121,31&width=300&height=300&zoom=15:

Baidu map tile

Random implementations I've found on GitHub:

Part of other projects

@piscis
Copy link

piscis commented Jun 23, 2015

+1 for Baidu integration

@kocokolo
Copy link

I found an article here
http://blog.csdn.net/qingyafan/article/details/49403989

@tschaub
Copy link
Member

tschaub commented May 31, 2016

Here are transforms for the Baidu Mercator / BD-09 projection: https://github.com/tschaub/projzh

This was a port of a Java implementation that was initially licensed with GPL v3. This has been relicensed with the MIT license (see tschaub/projzh#3 (comment)). So I can update the license for the JavaScript implementation. I think it would be appropriate to make a contribution to proj4js.

Here is an example of adding a layer with Baidu tiles to an OpenLayers map (using the above projzh library):

var projzh = require('projzh');

var extent = [72.004, 0.8293, 137.8347, 55.8271];

var baiduMercator = new ol.proj.Projection({
  code: 'baidu',
  extent: ol.extent.applyTransform(extent, projzh.ll2bmerc),
  units: 'm'
});

ol.proj.addProjection(baiduMercator);
ol.proj.addCoordinateTransforms('EPSG:4326', baiduMercator, projzh.ll2bmerc, projzh.bmerc2ll);
ol.proj.addCoordinateTransforms('EPSG:3857', baiduMercator, projzh.smerc2bmerc, projzh.bmerc2smerc);

var bmercResolutions = new Array(19);
for (var i = 0; i < 19; ++i) {
  bmercResolutions[i] = Math.pow(2, 18 - i);
}

var urls = [0, 1, 2, 3, 4].map(function(sub) {
  return 'http://shangetu' + sub +
      '.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46&udt=20150601';
});

var baidu = new ol.layer.Tile({
  source: new ol.source.XYZ({
    projection: 'baidu',
    maxZoom: 18,
    tileUrlFunction: function(tileCoord) {
      var x = tileCoord[1];
      var y = tileCoord[2];
      var z = tileCoord[0];
      var hash = (x << z) + y;
      var index = hash % urls.length;
      index = index < 0 ? index + urls.length : index;
      return urls[index].replace('{x}', x).replace('{y}', y).replace('{z}', z);
    },
    tileGrid: new ol.tilegrid.TileGrid({
      resolutions: bmercResolutions,
      origin: [0, 0],
      extent: ol.extent.applyTransform(extent, projzh.ll2bmerc),
      tileSize: [256, 256]
    })
  })
});

@yangfl
Copy link

yangfl commented Sep 29, 2016

Just FYI, I've found Baidu Mercator projection is based on Clarke 1866. Here's a sample code I manage to write in proj4js (may be incomplete):

proj4.defs('EPSG:4008','+proj=longlat +ellps=clrk66 +no_defs')
proj4.defs('BD-MC','+proj=merc +lon_0=0 +units=m +ellps=clrk66 +no_defs')

Now you can use

projection: 'BD-MC',

and it will be projected to the right point just as EPSG:3857 does.

var baidu = new ol.layer.Tile({
  title: 'Baidu',
  source: new ol.source.XYZ({
    projection: 'BD-MC',
    maxZoom: 19,
    tileUrlFunction: function (tileCoord) {
      var URLS_LENGTH = 5

      var x = tileCoord[1]
      var y = tileCoord[2]
      var z = tileCoord[0]

      var hash = (x << z) + y
      var index = hash % URLS_LENGTH
      index = index < 0 ? index + URLS_LENGTH : index

      if (x < 0) {
        x = 'M' + (-x)
      }
      if (y < 0) {
        y = 'M' + (-y)
      }
      return 'http://online{}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl'
        .replace('{}', index).replace('{x}', x).replace('{y}', y).replace('{z}', z)
    },
    tileGrid: new ol.tilegrid.TileGrid({
      extent: ol.proj.transformExtent([-180, -74, 180, 74], 'EPSG:4326', 'BD-MC'),
      origin: [0, 0],
      minZoom: 3,
      // note that resolution could be 0.5
      resolutions: [
        262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048,
        1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0.5,
      ],
    }),
  })
})

Hope it can be useful for someone googling to here.

@EV71
Copy link

EV71 commented Jan 27, 2018

为什么用Openlayers加载百度地图,显示起来会比较模糊,好像被缩小了。。。坐标是对的

@yangfl
Copy link

yangfl commented Jan 27, 2018

@EV71 是的,克拉克1866确实比常用的3857椭球体大

@EV71
Copy link

EV71 commented Jan 28, 2018

@yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@yangfl
Copy link

yangfl commented Jan 28, 2018

@EV71 我也只是尝试过openlayers,没有用过其他库,不知道其他是怎么实现的。不过可以肯定的是,Openlayers的缩放比例尺和百度的对不上,Openlayers以度为单位,而百度以米为单位,这之间肯定存在图片伸缩问题。我建议你在方面研究一下。

@idrinkjava
Copy link

@yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71 关于百度瓦片缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢

@Liquid-Zhangliquan
Copy link

@idrinkjava Hi,you can see the example maptalks-baidu,Maybe can help you TileConfigSpec

@Liquid-Zhangliquan
Copy link

maptalks-TileLayerSpec

@stale
Copy link

stale bot commented May 22, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@chenyu51
Copy link

ol6,这些方案就不好使了

@zhangjin747
Copy link

@chenyu51 我在上面代码的基础上改了一部分,虽然整体看上去好像没啥问题,但是地图两端感觉还是缺失了一部分,而且文字也很小很模糊

import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import Tile from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import TileGrid from "ol/tilegrid/TileGrid";
import { Projection, addProjection, addCoordinateTransforms, transform } from "ol/proj";
import projzh from "projzh";

var bd09Extent = [-20037726.37, -12474104.17, 20037726.37, 12474104.17];
var baiduMercator = new Projection({
  code: "baidu",
  extent: bd09Extent,
  units: "m"
});
addProjection(baiduMercator);
addCoordinateTransforms("EPSG:4326", baiduMercator, projzh.ll2bmerc, projzh.bmerc2ll);
addCoordinateTransforms("EPSG:3857", baiduMercator, projzh.smerc2bmerc, projzh.bmerc2smerc);

var bmercResolutions = new Array(19);
for (var i = 0; i < 19; ++i) {
  bmercResolutions[i] = Math.pow(2, 18 - i);
}

var urls = [0, 1, 2, 3].map(function(sub) {
  return (
    "http://maponline" +
    sub +
    ".bdimg.com/tile/?qt=vtile&x={x}&y={y}&z={z}&styles=pl&scaler=1&udt=20191119"
  );
});
var baidu = new Tile({
  source: new XYZ({
    projection: "baidu",
    maxZoom: 18,
    tileUrlFunction: function(tileCoord) {
      var x = tileCoord[1];
      var y = -tileCoord[2] - 1;
      var z = tileCoord[0];
      var hash = (x << z) + y;
      var index = hash % urls.length;
      index = index < 0 ? index + urls.length : index;
      if (x < 0) {
        x = "M" + -x;
      }
      if (y < 0) {
        y = "M" + -y;
      }
      return urls[index] .replace("{x}", x).replace("{y}", y) .replace("{z}", z);
    },
    tileGrid: new TileGrid({
      resolutions: bmercResolutions,
      origin: [0, 0]
    })
  })
});
var map = new Map({
  target: "map",
  layers: [baidu],
  view: new View({
    center: transform([121.51, 31.55], "EPSG:4326", "baidu"),
    zoom: 1,
    projection: "baidu",
    extent: bd09Extent
  })
});

@coderlee
Copy link

@yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71 关于百度瓦片缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢

最近我正好也遇到这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。

@EV71
Copy link

EV71 commented Apr 26, 2020 via email

@helion2017
Copy link

这简直是太好了,请分享你的成果。

------------------ 原始邮件 ------------------ 发件人: "Lee"<notifications@github.com>; 发送时间: 2020年4月26日(星期天) 上午10:35 收件人: "openlayers/openlayers"<openlayers@noreply.github.com>; 抄送: "Bill"<4669027@qq.com>; "Mention"<mention@noreply.github.com>; 主题: Re: [openlayers/openlayers] Add Baidu layer (#3522) @yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常? @EV71 关于百度瓦片缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢 最近我正好也遇到这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

请问使用zoom控件也有这个问题吗?我使用zoom时都会加载对应级别瓦片,但用zoomslider或者mousewheel时怀疑因为比例尺和瓦片级别不对应产生了模糊。

@EV71
Copy link

EV71 commented May 17, 2020

@yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71 关于百度瓦片缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢

最近我正好也遇到这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。

大哥,你什么时候能分享一下。

@siyugongzi
Copy link

siyugongzi commented Jun 17, 2020

openlayers 6.x/5.x 解决加载百度地图模糊:
【1】openlayers 6.x :①首先调节百度瓦片参数 scaler,把参数调为 scaler=2;②我是使用 TileImage 加载的,然后设置父类参数 tilePixelRatio: 2;③调整地图 view 的属性,属性设置为constrainResolution: true;④关于百度地图偏移问题,直接使用 prozh 里的算法重新定义坐标系即可;
【2】openlayers 5.x : 不要设置【1】中③即可,其他步骤调一遍就可以;
image
image

@huanianjwt
Copy link

@yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71 关于百度瓦片缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢

最近我正好也遇到这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。

请问模糊问题是怎么解决的呢,我也碰到这个了

@thsgar
Copy link

thsgar commented Jul 28, 2020

想让高德、腾迅的

I want it also,long time pass,your target has resolved ?could you share with me?thx very match!

@wuli-wangzj
Copy link

@yangfl有什么办法令其不模糊呢?我看过一些传单加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏的OpenLayers不正常?

@ EV71关于百度压缩缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢

最近我正好也遇到这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。
大佬求教啊

@coderlee
Copy link

coderlee commented Sep 8, 2020

@yangfl 有什么办法令其不模糊呢?我看过一些leaflets加载百度地图的例子,显示完全正常,坐标也对。也用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71 关于百度瓦片缩小模糊的问题你这边后来又解决吗?怎么解决的能分享下吗?谢谢

最近我正好也遇到这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。

大哥,你什么时候能分享一下。

@wuli-wangzj @EV71 @yangfl @huanianjwt
实在抱歉,最近实在是太忙了,本来想写个博客分享一下解决的过程的,一直没时间,还是直接给出最终的方法吧。
其实解决的方法很简单:用512或者更大的瓦片,调用地图时z减1,TileGrid的tileSize设置为[512,512]。这样显示的地图就很清晰了。

另外,各位如何纠偏的?我用了一个常用的转换算法,还是有偏移,用orgin参数做了修正,但是只在一个小范围内有效。

@hy31337
Copy link

hy31337 commented Apr 30, 2021

WGS EPSG:4326 AND EPSG:3857 map Mutual conversion,Switch to each other ???
WGS EPSG:4326 AND EPSG:3857 地图底图相互转换、相互切换怎么实现呢?

@JishuaiWang
Copy link

Here are transforms for the Baidu Mercator / BD-09 projection: https://github.com/tschaub/projzh
This was a port of a Java implementation that was initially licensed with GPL v3. This has been relicensed with the MIT license (see tschaub/projzh#3 (comment)). So I can update the license for the JavaScript implementation. I think it would be appropriate to make a contribution to proj4js.
Here is an example of adding a layer with Baidu tiles to an OpenLayers map (using the above projzh library):

var projzh = require('projzh');

var extent = [72.004, 0.8293, 137.8347, 55.8271];

var baiduMercator = new ol.proj.Projection({
  code: 'baidu',
  extent: ol.extent.applyTransform(extent, projzh.ll2bmerc),
  units: 'm'
});

ol.proj.addProjection(baiduMercator);
ol.proj.addCoordinateTransforms('EPSG:4326', baiduMercator, projzh.ll2bmerc, projzh.bmerc2ll);
ol.proj.addCoordinateTransforms('EPSG:3857', baiduMercator, projzh.smerc2bmerc, projzh.bmerc2smerc);

var bmercResolutions = new Array(19);
for (var i = 0; i < 19; ++i) {
  bmercResolutions[i] = Math.pow(2, 18 - i);
}

var urls = [0, 1, 2, 3, 4].map(function(sub) {
  return 'http://shangetu' + sub +
      '.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46&udt=20150601';
});

var baidu = new ol.layer.Tile({
  source: new ol.source.XYZ({
    projection: 'baidu',
    maxZoom: 18,
    tileUrlFunction: function(tileCoord) {
      var x = tileCoord[1];
      var y = tileCoord[2];
      var z = tileCoord[0];
      var hash = (x << z) + y;
      var index = hash % urls.length;
      index = index < 0 ? index + urls.length : index;
      return urls[index].replace('{x}', x).replace('{y}', y).replace('{z}', z);
    },
    tileGrid: new ol.tilegrid.TileGrid({
      resolutions: bmercResolutions,
      origin: [0, 0],
      extent: ol.extent.applyTransform(extent, projzh.ll2bmerc),
      tileSize: [256, 256]
    })
  })
});

Your great work help me to easy solve the problem about how to make the BAIDU MAP showing correctly under the mode of EPSG:3857 in Openlayers5.x, thanks!

now, another map named TENCENT MAP, whose coordinates system is GCJ-02, can you solve it like to BAIDU MAP?

TENCENT MAP tiles type:http://rt0.map.gtimg.com/tile?styleid=0&z=13&x=6731&y=4804

@whzc2020 请问GCJ-02的纠偏解决了吗?

@JishuaiWang
Copy link

GCJ-02的纠偏。
@whzc2020 能分享一下吗?

@JishuaiWang
Copy link

@whzc2020 想了解针对加载高德地图(GCJ-02)的瓦片的纠偏。
这个问题【解决高德、腾迅等GCJ-02坐标系下的瓦片底图偏移问题?我想让高德、腾迅的瓦片能在OPENLAYERS5.X的3857下正常显示。】

@JishuaiWang
Copy link

@whzc2020 需要背景地图的兼容即 : gcj02和wgs84完美重叠展示

@JishuaiWang
Copy link

@whzc2020 谢谢分享!

@hy31337
Copy link

hy31337 commented Jun 17, 2021

@whzc2020 @whzc2020 感谢分享,很强大,请问下这个在MapBox GL 下怎么实现哦

@yecb
Copy link

yecb commented Oct 15, 2021

@whzc2020 请问在哪里可以看到你的分享?谢谢!

@astadon
Copy link

astadon commented Dec 16, 2021

@whzc2020 感谢分享,请问gcj02纠偏有案例吗

@dbauszus-glx
Copy link

dbauszus-glx commented Nov 1, 2023

I created a codepen for this.

https://codepen.io/dbauszus-glx/pen/LYqZaNE

Wouldn't have been able to solve this without user Mike on stackoverflow.

https://gis.stackexchange.com/questions/469449/autonavi-amap-xyz-tile-layer-appears-shifted-in-openlayers-chinese-web-mercat

@prusswan
Copy link

prusswan commented Nov 6, 2023

I created a "pure" ES6/React version with debug coordinates using information from various contributors:

https://codesandbox.io/s/clever-rhodes-c9qdg4

For comparison and checking of alignment issues, there is a related plugin for mapboxgl: http://raw.githack.com/gisarmory/mapboxgl.InternetMapCorrection/main/examples/rasterTileLayer.html#12.44/30.28623/120.29269

Btw, Baidu maps seem to be misaligned for regions outside of China (even with corrections applied), and the transformation code does contain checks for China bounding box. Not sure if this is a "feature" of Baidu projection, or whether the transformation code can be further tweaked.

@KAN-007
Copy link

KAN-007 commented Mar 6, 2024

@yangfl有什么办法令其不模糊呢?我看了一些传单百度加载地图的例子,显示完全正常,坐标也对。还用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71关于百度瓦片缩小模糊的问题你布拉格又解决了吗?怎么解决的能分享下吗?谢谢

最近我也遇到了这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。

可以分享一下如何解决,openlayers6加载百度地图模糊的问题吗?

@KAN-007
Copy link

KAN-007 commented Mar 6, 2024

ee"<notificat

可以分享一下如何解决openlayer6加载百度地图模糊的问题吗?

@KAN-007
Copy link

KAN-007 commented Mar 6, 2024

?可以分享给我吗?谢谢非常般配!

大佬可以分享个demo。如何解决openlayer6模糊问题吗

@coderlee
Copy link

@yangfl有什么办法令其不模糊呢?我看了一些传单百度加载地图的例子,显示完全正常,坐标也对。还用过另外一个叫maptalk的,显示也正常,为什么偏偏Openlayers不正常?

@EV71关于百度瓦片缩小模糊的问题你布拉格又解决了吗?怎么解决的能分享下吗?谢谢

最近我也遇到了这个问题,研究之后解决了。如果感兴趣,我抽空写个博客分享一下。

可以分享一下如何解决,openlayers6加载百度地图模糊的问题吗?
我上面已经答复过了,方法很简单的,你翻看一下上面的答复。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests