leaflet +高德地图纠偏

该文展示了一个HTML页面,利用LeafletJavaScript库来创建地图,集成高德地图服务,并通过leaflet.ChineseTmsProviders.js处理中国地图提供商的坐标系统,包括天地图和高德地图的卫星、地形和普通图层。同时,通过leaflet.mapCorrection.min.js进行坐标偏移校正,以适应不同地图提供商的坐标差异。
摘要由CSDN通过智能技术生成

一、html源码

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <meta charset="utf-8" />
    <link
      rel="stylesheet"
      href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"
      integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
      crossorigin=""
    />
    <script
      src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
      integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
      crossorigin=""
    ></script>
    <script type="text/javascript" src="./js/leaflet.ChineseTmsProviders.js"></script>
    <!--纠偏-->
    <script type="text/javascript" src="./js/leaflet.mapCorrection.min.js"></script>

    <style>
      html,
      body {
        height: 100%;
        width: 100%;
        padding: 0;
        margin: 0;
      }
      #map {
        height: 100%;
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
  
    <script>
      var map = L.map('map', {
        center: [39.90554, 116.39133],
        zoom: 15,
        zoomControl: false
      });
      var gaodeMap = L.tileLayer.chinaProvider('GaoDe.Normal.Map').addTo(map);
      //设置参照物
      L.marker([39.90554, 116.39133])
        .addTo(map)
        .bindPopup('<p>我是WGS84坐标下,天安门广场国旗所在位置</p>');
     
    </script>
  </body>
</html>

二、leaflet.ChineseTmsProviders.js

// this L.CRS.Baidu from https://github.com/muyao1987/leaflet-tileLayer-baidugaode/blob/master/src/tileLayer.baidu.js

if (L.Proj) {
    L.CRS.Baidu = new L.Proj.CRS('EPSG:900913', '+proj=merc +a=6378206 +b=6356584.314245179 +lat_ts=0.0 +lon_0=0.0 +x_0=0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs', {
        resolutions: function () {
            level = 19
            var res = [];
            res[0] = Math.pow(2, 18);
            for (var i = 1; i < level; i++) {
                res[i] = Math.pow(2, (18 - i))
            }
            return res;
        }(),
        origin: [0, 0],
        bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244])
    });
}

L.TileLayer.ChinaProvider = L.TileLayer.extend({

    initialize: function(type, options) { // (type, Object)
        var providers = L.TileLayer.ChinaProvider.providers;

        options = options || {}

        var parts = type.split('.');

        var providerName = parts[0];
        var mapName = parts[1];
        var mapType = parts[2];

        var url = providers[providerName][mapName][mapType];
        options.subdomains = providers[providerName].Subdomains;
        options.key = options.key || providers[providerName].key;

        if ('tms' in providers[providerName]) {
            options.tms = providers[providerName]['tms']
        }

        L.TileLayer.prototype.initialize.call(this, url, options);
    }
});

L.TileLayer.ChinaProvider.providers = {
    TianDiTu: {
        Normal: {
            Map: "//t{s}.tianditu.com/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk={key}",
            Annotion: "//t{s}.tianditu.com/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk={key}"
        },
        Satellite: {
            Map: "//t{s}.tianditu.com/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk={key}",
            Annotion: "//t{s}.tianditu.com/DataServer?T=cia_w&X={x}&Y={y}&L={z}&tk={key}"
        },
        Terrain: {
            Map: "//t{s}.tianditu.com/DataServer?T=ter_w&X={x}&Y={y}&L={z}&tk={key}",
            Annotion: "//t{s}.tianditu.com/DataServer?T=cta_w&X={x}&Y={y}&L={z}&tk={key}"
        },
        Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
        key: "174705aebfe31b79b3587279e211cb9a"
    },

    GaoDe: {
        Normal: {
            Map: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
        },
        Satellite: {
            Map: '//webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
            Annotion: '//webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}'
        },
        Subdomains: ["1", "2", "3", "4"]
    },

    Google: {
        Normal: {
            Map: "//www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}"
        },
        Satellite: {
            Map: "//www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}",
            Annotion: "//www.google.cn/maps/vt?lyrs=y@189&gl=cn&x={x}&y={y}&z={z}"
        },
        Subdomains: []
    },

    Geoq: {
        Normal: {
            Map: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}",
            PurplishBlue: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
            Gray: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}",
            Warm: "//map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{y}/{x}",
        },
        Theme: {
            Hydro: "//thematic.geoq.cn/arcgis/rest/services/ThematicMaps/WorldHydroMap/MapServer/tile/{z}/{y}/{x}"
        },
        Subdomains: []
    },

    OSM: {
        Normal: {
            Map: "//{s}.tile.osm.org/{z}/{x}/{y}.png",
        },
        Subdomains: ['a', 'b', 'c']
    },

    Baidu: {
        Normal: {
            Map: '//online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1'
        },
        Satellite: {
            Map: '//shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46',
            Annotion: '//online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=020'
        },
        Subdomains: '0123456789',
        tms: true
    }

};

L.tileLayer.chinaProvider = function(type, options) {
    return new L.TileLayer.ChinaProvider(type, options);
};

三、leaflet.mapCorrection.min.js

L.CoordConver = function() {
    function a(b, c) {
        var d = -100 + 2 * b + 3 * c + .2 * c * c + .1 * b * c + .2 * Math.sqrt(Math.abs(b))
          , d = d + 2 * (20 * Math.sin(6 * b * e) + 20 * Math.sin(2 * b * e)) / 3
          , d = d + 2 * (20 * Math.sin(c * e) + 40 * Math.sin(c / 3 * e)) / 3;
        return d += 2 * (160 * Math.sin(c / 12 * e) + 320 * Math.sin(c * e / 30)) / 3
    }
    function f(b, c) {
        var d = 300 + b + 2 * c + .1 * b * b + .1 * b * c + .1 * Math.sqrt(Math.abs(b))
          , d = d + 2 * (20 * Math.sin(6 * b * e) + 20 * Math.sin(2 * b * e)) / 3
          , d = d + 2 * (20 * Math.sin(b * e) + 40 * Math.sin(b / 3 * e)) / 3;
        return d += 2 * (150 * Math.sin(b / 12 * e) + 300 * Math.sin(b / 30 * e)) / 3
    }
    this.getCorrdType = function(b) {
        var c = "wgs84";
        switch (b.split(".")[0]) {
        case "Geoq":
        case "GaoDe":
        case "Google":
            c = "gcj02";
            break;
        case "Baidu":
            c = "bd09";
            break;
        case "OSM":
        case "TianDiTu":
            c = "wgs84"
        }
        return c
    }
    ;
    this.bd09_To_gps84 = function(b, c) {
        var d = this.bd09_To_gcj02(b, c);
        return this.gcj02_To_gps84(d.lng, d.lat)
    }
    ;
    this.gps84_To_bd09 = function(b, c) {
        var d = this.gps84_To_gcj02(b, c);
        return this.gcj02_To_bd09(d.lng, d.lat)
    }
    ;
    this.gps84_To_gcj02 = function(b, c) {
        var d = a(b - 105, c - 35)
          , k = f(b - 105, c - 35)
          , l = c / 180 * e
          , g = Math.sin(l)
          , g = 1 - n * g * g
          , m = Math.sqrt(g)
          , d = 180 * d / (h * (1 - n) / (g * m) * e)
          , k = 180 * k / (h / m * Math.cos(l) * e);
        return {
            lng: b + k,
            lat: c + d
        }
    }
    ;
    this.gcj02_To_gps84 = function(b, c) {
        var d = a(b - 105, c - 35)
          , k = f(b - 105, c - 35)
          , l = c / 180 * e
          , g = Math.sin(l)
          , g = 1 - n * g * g
          , m = Math.sqrt(g)
          , d = 180 * d / (h * (1 - n) / (g * m) * e)
          , k = 180 * k / (h / m * Math.cos(l) * e);
        return {
            lng: 2 * b - (b + k),
            lat: 2 * c - (c + d)
        }
    }
    ;
    this.gcj02_To_bd09 = function(b, c) {
        var d = Math.sqrt(b * b + c * c) + 2E-5 * Math.sin(c * p)
          , a = Math.atan2(c, b) + 3E-6 * Math.cos(b * p);
        return {
            lng: d * Math.cos(a) + .0065,
            lat: d * Math.sin(a) + .006
        }
    }
    ;
    this.bd09_To_gcj02 = function(b, c) {
        var d = b - .0065
          , a = c - .006
          , e = Math.sqrt(d * d + a * a) - 2E-5 * Math.sin(a * p)
          , d = Math.atan2(a, d) - 3E-6 * Math.cos(d * p);
        return {
            lng: e * Math.cos(d),
            lat: e * Math.sin(d)
        }
    }
    ;
    var e = 3.141592653589793
      , h = 6378245
      , n = .006693421622965943
      , p = 3E3 * e / 180
}
;
L.coordConver = function() {
    return new L.CoordConver
}
;
L.TileLayer.ChinaProvider.include({
    addTo: function(a) {
        a.options.corrdType || (a.options.corrdType = this.options.corrdType);
        a.addLayer(this);
        return this
    }
});
L.tileLayer.chinaProvider = function(a, f) {
    f = f || {};
    f.corrdType = L.coordConver().getCorrdType(a);
    return new L.TileLayer.ChinaProvider(a,f)
}
;
L.GridLayer.include({
    _setZoomTransform: function(a, f, e) {
        var h = f;
        void 0 != h && this.options && ("gcj02" == this.options.corrdType ? h = L.coordConver().gps84_To_gcj02(f.lng, f.lat) : "bd09" == this.options.corrdType && (h = L.coordConver().gps84_To_bd09(f.lng, f.lat)));
        f = this._map.getZoomScale(e, a.zoom);
        e = a.origin.multiplyBy(f).subtract(this._map._getNewPixelOrigin(h, e)).round();
        L.Browser.any3d ? L.DomUtil.setTransform(a.el, e, f) : L.DomUtil.setPosition(a.el, e)
    },
    _getTiledPixelBounds: function(a) {
        var f = a;
        void 0 != f && this.options && ("gcj02" == this.options.corrdType ? f = L.coordConver().gps84_To_gcj02(a.lng, a.lat) : "bd09" == this.options.corrdType && (f = L.coordConver().gps84_To_bd09(a.lng, a.lat)));
        a = this._map;
        var e = a._animatingZoom ? Math.max(a._animateToZoom, a.getZoom()) : a.getZoom()
          , e = a.getZoomScale(e, this._tileZoom)
          , f = a.project(f, this._tileZoom).floor();
        a = a.getSize().divideBy(2 * e);
        return new L.Bounds(f.subtract(a),f.add(a))
    }
});

 参考链接:leaflet中如何优雅的解决百度、高德地图的偏移问题 | 地图

Leaflet是一个流行的JavaScript库,用于创建交互式的地图应用。在 Leaflet 中,点位纠偏通常是针对地图上的标记位置可能存在误差的情况。当GPS数据不精确,或者手动输入的位置有误时,可能会需要对地图上的标记进行调整。 要在 Leaflet 中实现点位纠偏,可以参考以下几个步骤: 1. **创建定位标记**:首先,你需要创建一个 `L.Marker` 对象,并将其放置在你认为正确的地理位置。例如: ```javascript var marker = L.marker([latitude, longitude], { title: '位置' }).addTo(map); ``` 2. **用户交互回调**:添加事件监听器(如点击事件)以便用户可以编辑标记位置: ```javascript marker.on('click', function(e) { var latlng = e.latlng; // 获取当前鼠标点击的经纬度 // 提供一个弹出窗口让用户输入新坐标,或者直接修改latlng属性 latlng.setLatLng(newLatLng); // newLatLng是你获取的新位置 }); ``` 3. **实时更新**:每当用户更改了标记位置,都要确保地图同步更新: ```javascript map.setView(latlng, zoomLevel); // zoomLevel是所需的缩放级别 ``` 至于比例尺的显示,Leaflet提供了内置的功能。你可以通过调用 `map.getZoom()` 来获取当前的缩放级别,然后在地图的控制元素中显示比例尺。在HTML模板中加入比例尺控件: ```html < div id="scaleControl" class="leaflet-control-scale"></div> ``` 在JavaScript中初始化并添加到地图上: ```javascript var scaleControl = L.control.scale().addTo(map); ``` 现在,地图的比例尺会随着用户的缩放操作实时更新。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值