Leaflet(无需 proj4 和 proj4leaflet 库) 和 Cesium 加载纠偏后百度地图在线瓦片,百度地图最新最全在线瓦片地址

百度地图地址

百度地图在线瓦片分两种,分别是

//maponline{s}.bdimg.com/starpic/u=x={x};y={y};z={z};v=009;type=sate&qt=satepc&fm=46&app=webearth2&v=009 /*影像底图地址*/
//maponline{s}.bdimg.com/tile/?x={x}&y={y}&z={z}&{p} /*其他电子地图、标注底图等的地址*/

不过,上述地址中的域名 maponline{s}.bdimg.com 可以替换成 online{s}.map.bdimg.comshangetu{s}.map.bdimg.com,三个域名都可以访问。
百度地图采用 BD09 百度坐标系,叠加到 Leaflet 和 Cesium 默认的 WGS84 通用坐标系需要进行纠偏。

相关参数:

  • {s} 是可用的子域之一,用于克服浏览器对每个主机的并发请求数的限制,支持 0123。
  • {x} 是 TMS 切片方案中的图块 X 坐标,其中 0 是最西端的图块。
  • {y} 是 TMS 切片方案中的图块 Y 坐标,其中 0 是最南端的图块。
  • {z} 是 TMS 切片方案中切片的级别,零级是四叉树金字塔的根。
  • {p} 是以下加载代码中封装的自定义请求参数 param,具体参见下表和代码,下表内容在测试中得出,欢迎指正和补充。
{p}(代码中 param 参数)对应图层瓦片级别
img影像底图[1,19]
qt=vtile&styles=sl&showtext=0&scaler=1&v=083影像标注,路网[1,20]
qt=vtile&styles=sl&showtext=1&scaler=1&v=083影像标注,路网 + 注记[3,20]
qt=vtile&styles=sl&showtext=1&scaler=2&v=083影像标注,路网 + 高清注记[3,19]
qt=vtile&styles=pl&showtext=0&scaler=1&v=083电子地图,图形[3,20]
qt=vtile&styles=pl&showtext=1&scaler=1&v=083电子地图,图形 + 注记[3,20]
qt=vtile&styles=pl&showtext=1&scaler=2&v=083电子地图,图形 + 高清注记[3,19]
qt=vtile&styles=ph&showtext=0&scaler=1&v=083大字体电子地图,图形[3,20]
qt=vtile&styles=ph&showtext=1&scaler=1&v=083大字体电子地图,图形 + 注记[3,20]
qt=tile&styles=sl&showtext=1&scaler=1&v=083旧版影像标注,路网 + 注记[3,19]
qt=tile&styles=sl&showtext=1&scaler=2&v=083旧版影像标注,路网 + 高清注记[3,19]
qt=tile&styles=pl&showtext=1&scaler=1&v=083旧版电子地图,图形 + 注记[3,19]
qt=tile&styles=pl&showtext=1&scaler=2&v=083旧版电子地图,图形 + 高清注记[3,19]
qt=tile&styles=ph&showtext=1&scaler=1&v=083旧版大字体电子地图,图形 + 注记[3,19]

Leaflet 添加代码

在线运行

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8">
    <style type="text/css">
      body { padding: 0; margin: 0; }
      html, body, #map { height: 100%; }
      #param-test { position: absolute; z-index: 999; left: 10px; top: 10px; background: white; padding: 0 3px; line-height: 28px; font-size: 14px }
      #url-input {  width: 450px; height: 18px; margin-bottom: 3px; }
    </style>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.2/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.9.2/dist/leaflet.js"></script>
    <script src="https://unpkg.com/gcoord@0.3.2/dist/gcoord.js"></script>
  </head>
  <body>
    <div id="param-test">
      测试参数:<input id="url-input" type="text" placeholder="输入地址参数, 例:qt=vtile&styles=sl&showtext=0&scaler=1&v=083 或 img, 并回车" onkeydown="loadTile(this.value)" />
    </div>
    <div id="map" />
  </body>
  <script type="text/javascript">
    L.Projection.BaiduMercator = L.Util.extend({}, L.Projection.Mercator, {
      R: 6378206, //百度椭球赤道半径 a=6378206,相当于在 WGS84 椭球赤道半径上加了 69 米
      R_MINOR: 6356584.314245179, //百度椭球极半径 b=6356584.314245179,相当于在 WGS84 椭球极半径上减了 168 米
      bounds: new L.Bounds([-20037725.11268234, -19994619.55417086], [20037725.11268234, 19994619.55417086]) //数据覆盖范围在经度[-180°,180°],纬度[-85.051129°, 85.051129°]之间
    })
    L.CRS.Baidu = L.Util.extend({}, L.CRS.Earth, {
      code: 'EPSG:Baidu',
      projection: L.Projection.BaiduMercator,
      transformation: new L.transformation(1, 0.5, -1, 0.5),
      scale: function (zoom) { return 1 / Math.pow(2, (18 - zoom)) },
      zoom: function (scale) { return 18 - Math.log(1 / scale) / Math.LN2 },
      wrapLng: undefined
    })
    L.TileLayer.BaiDuTileLayer = L.TileLayer.extend({
      initialize: function (param, options) {
        var templateImgUrl = "//maponline{s}.bdimg.com/starpic/u=x={x};y={y};z={z};v=009;type=sate&qt=satepc&fm=46&app=webearth2&v=009"
        var templateUrl = "//maponline{s}.bdimg.com/tile/?x={x}&y={y}&z={z}&{p}"
        var myUrl = (param === "img" ? templateImgUrl : templateUrl)
        options = L.extend({
          getUrlArgs: (o) => { return { x: o.x, y: (-1 - o.y), z: o.z } },
          p: param, subdomains: "0123", minZoom: 0, maxZoom: 23, minNativeZoom: 1, maxNativeZoom: 18
        }, options)
        L.TileLayer.prototype.initialize.call(this, myUrl, options)
      },
      getTileUrl: function (coords) {
        if (this.options.getUrlArgs) {
          return L.Util.template(this._url, L.extend({ s: this._getSubdomain(coords), r: L.Browser.retina ? '@2x' : '' }, this.options.getUrlArgs(coords), this.options))
        } else {
          return L.TileLayer.prototype.getTileUrl.call(this, coords)
        }
      },
      _setZoomTransform: function (level, center, zoom) {
        center = L.latLng(gcoord.transform([center.lng, center.lat], gcoord.WGS84, gcoord.BD09).reverse()) // 采用 gcoord 库进行纠偏
        L.TileLayer.prototype._setZoomTransform.call(this, level, center, zoom)
      },
      _getTiledPixelBounds: function (center) {
        center = L.latLng(gcoord.transform([center.lng, center.lat], gcoord.WGS84, gcoord.BD09).reverse()) // 采用 gcoord 库进行纠偏
        return L.TileLayer.prototype._getTiledPixelBounds.call(this, center)
      }
    })
    L.tileLayer.baiDuTileLayer = function (param, options) { return new L.TileLayer.BaiDuTileLayer(param, options) }
    var img_Layer = L.tileLayer.baiDuTileLayer("img"), // 影像底图
      vsl01_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=sl&showtext=0&scaler=1&v=083") // 影像标注,路网
      vsl11_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=sl&showtext=1&scaler=1&v=083") // 影像标注,路网 + 注记
      vsl12_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=sl&showtext=1&scaler=2&v=083") // 影像标注,路网 + 高清注记
      vpl01_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=pl&showtext=0&scaler=1&v=083") // 电子地图,图形
      vpl11_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=pl&showtext=1&scaler=1&v=083") // 电子地图,图形 + 注记
      vpl12_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=pl&showtext=1&scaler=2&v=083") // 电子地图,图形 + 高清注记
      vph01_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=ph&showtext=0&scaler=1&v=083") // 大字体电子地图,图形
      vph11_Layer = L.tileLayer.baiDuTileLayer("qt=vtile&styles=ph&showtext=1&scaler=1&v=083") // 大字体电子地图,图形 + 注记
      
      _sl11_Layer = L.tileLayer.baiDuTileLayer("qt=tile&styles=sl&showtext=1&scaler=1&v=083") // 旧影像标注,路网 + 注记
      _sl12_Layer = L.tileLayer.baiDuTileLayer("qt=tile&styles=sl&showtext=1&scaler=2&v=083") // 旧影像标注,路网 + 高清注记
      _pl11_Layer = L.tileLayer.baiDuTileLayer("qt=tile&styles=pl&showtext=1&scaler=1&v=083") // 旧电子地图,图形 + 注记
      _pl12_Layer = L.tileLayer.baiDuTileLayer("qt=tile&styles=pl&showtext=1&scaler=2&v=083") // 旧电子地图,图形 + 高清注记
      _ph11_Layer = L.tileLayer.baiDuTileLayer("qt=tile&styles=ph&showtext=1&scaler=1&v=083") // 旧大字体电子地图,图形 + 注记

    var map = L.map("map", { crs: L.CRS.Baidu, center: [29.708050, 118.321499], zoom: 15, zoomControl: false, attributionControl: false, doubleClickZoom: false })
    var overlayLayers = {
      "影像底图": img_Layer, "影像标注,路网": vsl01_Layer, "影像标注,路网 + 注记": vsl11_Layer, "影像标注,路网 + 高清注记": vsl12_Layer, 
      "电子地图,图形": vpl01_Layer, "电子地图,图形 + 注记": vpl11_Layer, "电子地图,图形 + 高清注记": vpl12_Layer,
      "大字体电子地图,图形": vph01_Layer, "大字体电子地图,图形 + 注记": vph11_Layer, 
      "旧影像标注,路网 + 注记": _sl11_Layer, "旧影像标注,路网 + 高清注记": _sl12_Layer, 
      "旧电子地图,图形 + 注记": _pl11_Layer, "旧电子地图,图形 + 高清注记": _pl12_Layer, 
      "旧大字体电子地图,图形 + 注记": _ph11_Layer
    }
    L.control.layers([], overlayLayers, { autoZIndex: false }).addTo(map)
    L.marker([29.708050, 118.321499]).addTo(map) // 添加点用于纠偏测试
    // map.on('dblclick', function (e) { console.dir(e.latlng.lng + "," + e.latlng.lat) })
    
    var test_Layer = null
    function loadTile (param) {
      if (!window.event || window.event.keyCode === 13) { // keyCode ===13 表示按下回车
        if (test_Layer !== null) {
          map.removeLayer(test_Layer)
          test_Layer = null
        }
        if (!param) return
        test_Layer = L.tileLayer.baiDuTileLayer(param)
        map.addLayer(test_Layer)
      }
    }
    var param = "img"
    document.getElementById("url-input").value = param
    loadTile(param)
  </script>
</html>

Cesium 添加代码

在线运行

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="utf-8" />
    <style type="text/css">
      body { padding: 0; margin: 0; }
      html, body, #map { height: 100%; }
      #param-test { position: absolute; z-index: 999; left: 10px; top: 10px; background: white; padding: 0 3px; line-height: 28px; font-size: 14px }
      #url-input {  width: 450px; height: 18px; margin-bottom: 3px; }
      .cesium-viewer .cesium-viewer-bottom { display: none; }
      .cesium-viewer .cesium-baseLayerPicker-item { display: block; width: auto; margin: 3px 10px; }
      .cesium-viewer .cesium-baseLayerPicker-itemIcon, .cesium-viewer .cesium-baseLayerPicker-sectionTitle { display: none; }
      .cesium-viewer .cesium-baseLayerPicker-itemLabel { text-align: left; }
      .cesium-viewer .cesium-baseLayerPicker-dropDown { width: 250px; padding: 0; margin: 0; }
      .cesium-viewer .cesium-baseLayerPicker-choices { border: none; }
      .cesium-viewer .cesium-baseLayerPicker-selectedItem .cesium-baseLayerPicker-itemLabel { color: #00cbff; }
    </style>
    <link rel="stylesheet" href="https://unpkg.com/cesium@1.98.1/Build/Cesium/Widgets/widgets.css" />
    <script src="https://unpkg.com/cesium@1.98.1/Build/Cesium/Cesium.js"></script>
    <script src="https://unpkg.com/gcoord@0.3.2/dist/gcoord.js"></script>
  </head>
  <body>
    <div id="param-test">
      测试参数:<input id="url-input" type="text" placeholder="输入地址参数, 例:qt=vtile&styles=sl&showtext=0&scaler=1&v=083 或 img, 并回车" onkeydown="loadTile(this.value)" />
    </div>
    <div id="map" />
  </body>
  <script type="text/javascript">
    class BaiduMercatorProjection { // 创建椭球墨卡托投影,Cesium 源码中是以xyz三个轴的最长的轴作为球来计算
      constructor (ellipsoid) {
        this._ellipsoid = Cesium.defaultValue(ellipsoid, Cesium.Ellipsoid.WGS84)
        this._semimajorAxis = this._ellipsoid.maximumRadius
        this._oneOverSemimajorAxis = 1.0 / this._semimajorAxis
      }
      get ellipsoid () { return this._ellipsoid }
      get MaximumLatitude () { return this.mercatorAngleToGeodeticLatitude(Math.PI) }
      geodeticLatitudeToMercatorAngle (latitude) {
        if (latitude > this.MaximumLatitude) { latitude = this.MaximumLatitude }
        else if (latitude < -this.MaximumLatitude) { latitude = -this.MaximumLatitude }
        const tmp = this.ellipsoid.radii.z / this.ellipsoid.radii.x // 短半轴 / 长半轴
        const e = Math.sqrt(1.0 - tmp * tmp)
        const con = e * Math.sin(latitude)
        const ts = Math.tan(Math.PI * 0.25 - latitude * 0.5) / Math.pow((1.0 - con) / (1.0 + con), e * 0.5)
        return - Math.log(Math.max(ts, 1E-10))
      }
      project (cartographic, result) {
        const correct = gcoord.transform([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)], gcoord.WGS84, gcoord.BD09)
        cartographic.longitude = Cesium.Math.toRadians(correct[0]), cartographic.latitude = Cesium.Math.toRadians(correct[1])

        var x = cartographic.longitude * this.ellipsoid.radii.x
        var y = this.geodeticLatitudeToMercatorAngle(cartographic.latitude) * this.ellipsoid.radii.x
        var z = cartographic.height

        if (!Cesium.defined(result)) { return new Cesium.Cartesian3(x, y, z) }
        result.x = x, result.y = y, result.z = z
        return result
      }
      mercatorAngleToGeodeticLatitude (mercatorAngle) {
        const tmp = this.ellipsoid.radii.z / this.ellipsoid.radii.x // 短半轴 / 长半轴
        const e = Math.sqrt(1.0 - tmp * tmp)
        const ts = Math.exp(-mercatorAngle)
        var phi = Math.PI / 2 - 2 * Math.atan(ts)
        for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
          con = e * Math.sin(phi)
          con = Math.pow((1 - con) / (1 + con), e / 2)
          dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi
          phi += dphi
        }
        return phi
      }
      unproject (cartesian, result) {
        var longitude = cartesian.x / this.ellipsoid.radii.x
        var latitude = this.mercatorAngleToGeodeticLatitude(cartesian.y / this.ellipsoid.radii.x)
        var height = cartesian.z

        const correct = gcoord.transform([Cesium.Math.toDegrees(longitude), Cesium.Math.toDegrees(latitude)], gcoord.BD09, gcoord.WGS84)
        longitude = Cesium.Math.toRadians(correct[0]), latitude = Cesium.Math.toRadians(correct[1])

        if (!Cesium.defined(result)) { return new Cesium.Cartographic(longitude, latitude, height) }
        result.longitude = longitude, result.latitude = latitude, result.height = height
        return result
      }
    }
    Cesium.BaiduMercatorProjection = BaiduMercatorProjection
    class BaiduMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
      constructor (options) {
        super(options)
        this._projection = new Cesium.BaiduMercatorProjection(this._ellipsoid)
      }
    }
    Cesium.BaiduMercatorTilingScheme = BaiduMercatorTilingScheme
    class BaiduImageryProvider extends Cesium.UrlTemplateImageryProvider {
      constructor (param, options = {}) {
        var templateImgUrl = "//maponline{s}.bdimg.com/starpic/u=x={x};y={y};z={z};v=009;type=sate&fm=46&app=webearth2&v=009&qt=satepc"
        var templateUrl = "//maponline{s}.bdimg.com/tile/?x={x}&y={y}&z={z}&{p}"
        var myUrl = (param === "img" ? templateImgUrl : templateUrl).replace(/\{p\}/g, param)
        super(Object.assign({}, {
          url: myUrl, subdomains: "0123", minimumLevel: 1, maximumLevel: 18, tilingScheme: new Cesium.BaiduMercatorTilingScheme({
            rectangleSouthwestInMeters: new Cesium.Cartesian2(-33554432, -33554432),
            rectangleNortheastInMeters: new Cesium.Cartesian2(33554432, 33554432),
            ellipsoid: new Cesium.Ellipsoid(6378206, 6378206, 6356584.314245179)
          }),
        }, options))
        const that = this
        this._readyPromise.then(function (properties) {
          var customTags = { x: (l, x, y, z) => { return x - (1 << (z - 1)) }, y: (l, x, y, z) => { return (1 << (z - 1)) - y - 1 }, z: (l, x, y, z) => { return z } }
          that._tags = Cesium.combine(customTags, that._tags)
          that._pickFeaturesTags = Cesium.combine(customTags, that._pickFeaturesTags)
          that._rectangle = that._tilingScheme.rectangle
        })
      }
    }
    Cesium.BaiduImageryProvider = BaiduImageryProvider
    Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwNGNmNWUwMi02NWEyLTQxNzItOTNhNC1mY2NiZTcxNDc2OWYiLCJpZCI6MTU5NDQsInNjb3BlcyI6WyJhc2wiLCJhc3IiLCJhc3ciLCJnYyJdLCJpYXQiOjE1NjkyMjk3MTN9.PYUfCHykW23NuwRzzz04yW7JyZ4vQlcb4kToZ44r42w"
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(118.282527, 29.692229, 118.360733, 29.724694) // 设置相机默认范围为自定义区域
    Cesium.Camera.DEFAULT_VIEW_FACTOR = 0
    // console.debug(viewer.camera.computeViewRectangle()) // 可以返回当前区域矩形,以弧度为单位 
    var viewer = new Cesium.Viewer("map", {
      animation: false, // 是否显示动画控件
      baseLayerPicker: true, // 是否显示图层选择控件
      vrButton: false, // 是否显示VR控件
      fullscreenButton: false, // 是否显示全屏按钮
      geocoder: false, // 是否显示地名查找控件
      homeButton: false, // 是否显示返回主视角控件
      sceneModePicker: false, // 是否显示投影方式控件
      selectionIndicator: false, // 是否显示选中指示框
      timeline: false, // 是否显示时间线控件
      navigationHelpButton: false, // 是否显示帮助信息控件
      infoBox: false, // 是否显示点击要素之后显示的信息
    })
    viewer.imageryLayers.removeAll(viewer.imageryLayers.get(0)) // 移除 Cesium 默认图层
    viewer.scene.globe.baseColor = new Cesium.Color(0, 0, 0, 0)  // 设置地球背景色黑色

    var img_Layer = new Cesium.BaiduImageryProvider("img") // 影像底图
    vsl01_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=sl&showtext=0&scaler=1&v=083") // 影像标注,路网
    vsl11_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=sl&showtext=1&scaler=1&v=083") // 影像标注,路网 + 注记
    vsl12_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=sl&showtext=1&scaler=2&v=083") // 影像标注,路网 + 高清注记
    vpl01_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=pl&showtext=0&scaler=1&v=083") // 电子地图,图形
    vpl11_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=pl&showtext=1&scaler=1&v=083") // 电子地图,图形 + 注记
    vpl12_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=pl&showtext=1&scaler=2&v=083") // 电子地图,图形 + 高清注记
    vph01_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=ph&showtext=0&scaler=1&v=083") // 大字体电子地图,图形
    vph11_Layer = new Cesium.BaiduImageryProvider("qt=vtile&styles=ph&showtext=1&scaler=1&v=083") // 大字体电子地图,图形 + 注记

    _sl11_Layer = new Cesium.BaiduImageryProvider("qt=tile&styles=sl&showtext=1&scaler=1&v=083") // 旧影像标注,路网 + 注记
    _sl12_Layer = new Cesium.BaiduImageryProvider("qt=tile&styles=sl&showtext=1&scaler=2&v=083") // 旧影像标注,路网 + 高清注记
    _pl11_Layer = new Cesium.BaiduImageryProvider("qt=tile&styles=pl&showtext=1&scaler=1&v=083") // 旧电子地图,图形 + 注记
    _pl12_Layer = new Cesium.BaiduImageryProvider("qt=tile&styles=pl&showtext=1&scaler=2&v=083") // 旧电子地图,图形 + 高清注记
    _ph11_Layer = new Cesium.BaiduImageryProvider("qt=tile&styles=ph&showtext=1&scaler=1&v=083") // 旧大字体电子地图,图形 + 注记

    viewer.baseLayerPicker._dropPanel.children[0].innerHTML = "底图"
    viewer.baseLayerPicker.viewModel.imageryProviderViewModels = [
      new Cesium.ProviderViewModel({ creationFunction: function () { return img_Layer }, name: "影像底图" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vsl01_Layer }, name: " 影像标注,路网" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vsl11_Layer }, name: "影像标注,路网 + 注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vsl12_Layer }, name: "影像标注,路网 + 高清注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vpl01_Layer }, name: "电子地图,图形" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vpl11_Layer }, name: "电子地图,图形 + 注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vpl12_Layer }, name: "电子地图,图形 + 高清注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vph01_Layer }, name: "大字体电子地图,图形" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return vph11_Layer }, name: "大字体电子地图,图形 + 注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return _sl11_Layer }, name: "旧影像标注,路网 + 注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return _sl12_Layer }, name: "旧影像标注,路网 + 高清注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return _pl11_Layer }, name: "旧电子地图,图形 + 注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return _pl12_Layer }, name: "旧电子地图,图形 + 高清注记" }),
      new Cesium.ProviderViewModel({ creationFunction: function () { return _ph11_Layer }, name: "旧大字体电子地图,图形 + 注记" })
    ]
    // viewer.baseLayerPicker.viewModel.selectedImagery = viewer.baseLayerPicker.viewModel.imageryProviderViewModels[0]

    viewer.baseLayerPicker._dropPanel.children[2].innerHTML = "地形"
    viewer.baseLayerPicker.viewModel.terrainProviderViewModels = []
    viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(118.321499, 29.708050), point: { pixelSize: 5, color: Cesium.Color.RED } }) //添加点用于纠偏测试

    var test_Layer = null
    function loadTile (param) {
      if (!window.event || window.event.keyCode === 13) { // keyCode === 13 表示按下回车
        if (test_Layer !== null) {
          viewer.imageryLayers.remove(test_Layer, true)
          test_Layer = null
        }
        if (!param) return
        test_Layer = viewer.imageryLayers.addImageryProvider(new Cesium.BaiduImageryProvider(param))
      }
    }
    var param = "img"
    document.getElementById("url-input").value = param
    loadTile(param)
  </script>
</html>

参考链接

其他文章:https://zhuanlan.zhihu.com/p/363528840
百度地图控制台:https://map.baidu.com/

<think>好的,我现在需要处理用户关于前端GIS地图开发的查询。用户希望找到相关的资料或教程,特别是关于框架、教程的内容。首先,我需要回顾用户提供的引用内容,看看有没有直接相关的信息。 引用[1]提到WebGIS开发的地图可视化数据,特别是Echarts。这可能涉及到数据可视化的部分。引用[2]则列举了几个常见的GIS前端开发框架,虽然具体名称没有在引用中显示,但可能需要结合常见的开源框架来回答。引用[3]详细介绍了前端GIS开发的基础,包括关键技术工具,如Leaflet、OpenLayers、Mapbox GL JSCesium。这些信息应该对用户有帮助。 接下来,我需要根据这些引用内容整理出用户需要的答案。首先,常见的GIS开发框架有哪些?根据引用[2]引用[3],应该包括Leaflet、OpenLayers、MapBox GL JS、CesiumEcharts(虽然Echarts主要是可视化,但在地图方面也有应用)。然后,需要列出相关的工具,比如Turf.js、Proj4js、GDAL/OGR,这些可能用于地理数据处理坐标转换。 关于教程学习路径,需要分步骤,从基础知识开始,到框架学习、数据可视化、进阶内容以及项目实践。此外,社区资源部分,可以推荐官方文档、GitHub、Stack Overflow以及在线课程平台,如引用[3]提到的内容。 可能还需要生成相关问题,比如比较不同框架的优缺点,处理地理空间数据的方法,3D地图的实现,开源与商业框架的区别,以及性能优化技巧。这些相关问题可以帮助用户进一步探索。 最后,要确保回答结构清晰,符合用户要求的中文回答,正确使用LaTeX格式,行内公式用$...$,独立公式用$$...$$,但在这个问题中可能涉及数学公式较少,所以主要注意框架的正确引用,以及引用标识的添加。需要检查是否有遗漏的框架或工具,并确保所有信息准确,基于提供的引用内容。</think>### 前端GIS地图开发指南 #### 一、常见开发框架与 1. **Leaflet** - 轻量级开源框架,适合快速构建交互式地图,支持多种地图服务(如OpenStreetMap)[^2]。 - 示例代码: ```javascript const map = L.map('map').setView([51.505, -0.09], 13); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); ``` 2. **OpenLayers** - 功能强大的开源框架,支持多种地图格式(WMS、GeoJSON等)复杂空间分析[^3]。 3. **Mapbox GL JS** - 基于WebGL的高性能框架,支持矢量切片自定义样式,适合高交互性需求[^3]。 4. **Cesium** - 专注于3D地球时空数据可视化,支持地形、卫星影像动态数据渲染。 5. **ECharts** - 百度开源的图表,内置地理坐标系组件,适合轻量级地理数据可视化[^1]。 #### 二、核心工具与 - **Turf.js** 地理空间分析,提供缓冲区分析、距离计算等功能。 - **Proj4js** 坐标系转换工具,支持WGS84、UTM等坐标系的相互转换。 - **GDAL/OGR** 地理数据处理工具链,支持格式转换空间分析(需结合Node.js使用)。 #### 三、学习路径与教程 1. **基础知识** - 学习地理坐标系(如WGS84地图投影(如墨卡托投影)[^3]。 - 掌握GeoJSON格式,例如: ```json { "type": "Feature", "geometry": { "type": "Point", "coordinates": [116.4, 39.9] } } ``` 2. **框架入门** - **Leaflet官方教程**:[Leaflet Quick Start Guide](https://leafletjs.com/examples/quick-start/) - **OpenLayers案例**:[OpenLayers Examples](https://openlayers.org/en/latest/examples/) 3. **数据可视化** - 使用ECharts实现热力图: ```javascript option = { geo: { map: 'china' }, series: { type: 'heatmap', data: [[120, 30, 100], ...] } }; ``` 4. **进阶内容** - 通过Cesium加载3D地形: ```javascript const viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider: Cesium.createWorldTerrain() }); ``` #### 四、社区与资源 - **官方文档**:各框架官网提供详细API说明(如[Mapbox GL JS Docs](https://docs.mapbox.com/mapbox-gl-js/api/))。 - **GitHub仓**:搜索“webgis”、“geospatial”等关键词,获取开源项目代码。 - **在线课程**:平台如Udemy、Coursera提供GIS开发专项课程。 --- ###
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值