Leaflet 百度、高德地图瓦片坐标 偏移 纠偏

摘要:
varlontitude=lng*2门lng;varbd_ng=z*数学cos(θ)+0.0065;varbd_ lat=z*数学sin(θ)+0.006;变化=bd_ lat-0.006;vargg_ lng=z*数学cos(θ);vargg_ lat=z*数学sin(θ);vara=6378245.0;

实现地图瓦片纠偏的leaflet.mapCorrection.js代码:

Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第1张Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第2张
//坐标转换
L.CoordConvertor = function () {

    /**百度转84*/
    this.bd09_To_gps84 = function (lng, lat) {
        var gcj02 = this.bd09_To_gcj02(lng, lat);
        var map84 = this.gcj02_To_gps84(gcj02.lng, gcj02.lat);
        return map84;
    }

    /**84转百度*/
    this.gps84_To_bd09 = function (lng, lat) {
        var gcj02 = this.gps84_To_gcj02(lng, lat);
        var bd09 = this.gcj02_To_bd09(gcj02.lng, gcj02.lat);
        return bd09;
    }

    /**84转火星*/
    this.gps84_To_gcj02 = function (lng, lat) {
        var dLat = transformLat(lng - 105.0, lat - 35.0);
        var dLng = transformLng(lng - 105.0, lat - 35.0);
        var radLat = lat / 180.0 * pi;
        var magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        var sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        var mgLat = lat + dLat;
        var mgLng = lng + dLng;
        var newCoord = {
            lng: mgLng,
            lat: mgLat
        };
        return newCoord;
    }

    /**火星转84*/
    this.gcj02_To_gps84 = function (lng, lat) {
        var coord = transform(lng, lat);
        var lontitude = lng * 2 - coord.lng;
        var latitude = lat * 2 - coord.lat;
        var newCoord = {
            lng: lontitude,
            lat: latitude
        };
        return newCoord;
    }

    /**火星转百度*/
    this.gcj02_To_bd09 = function (x, y) {
        var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        var bd_lng = z * Math.cos(theta) + 0.0065;
        var bd_lat = z * Math.sin(theta) + 0.006;
        var newCoord = {
            lng: bd_lng,
            lat: bd_lat
        };
        return newCoord;
    }

    /**百度转火星*/
    this.bd09_To_gcj02 = function (bd_lng, bd_lat) {
        var x = bd_lng - 0.0065;
        var y = bd_lat - 0.006;
        var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        var gg_lng = z * Math.cos(theta);
        var gg_lat = z * Math.sin(theta);
        var newCoord = {
            lng: gg_lng,
            lat: gg_lat
        };
        return newCoord;
    }

    var pi = 3.1415926535897932384626;
    var a = 6378245.0;
    var ee = 0.00669342162296594323;
    var x_pi = pi * 3000.0 / 180.0;
    var R = 6378137;

    function transform(lng, lat) {
        var dLat = transformLat(lng - 105.0, lat - 35.0);
        var dLng = transformLng(lng - 105.0, lat - 35.0);
        var radLat = lat / 180.0 * pi;
        var magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        var sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        var mgLat = lat + dLat;
        var mgLng = lng + dLng;
        var newCoord = {
            lng: mgLng,
            lat: mgLat
        };
        return newCoord;
    }

    function transformLat(x, y) {
        var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    function transformLng(x, y) {
        var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }
}

L.coordConvertor = function () {
    return new L.CoordConvertor()
}

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

    //获取坐标类型
    function getCoordType(type) {
        var parts = type.split('.');
        var providerName = parts[0];
        var zbName = "wgs84"
        switch (providerName) {
            case "Geoq":
            case "GaoDe":
            case "Google":
                zbName = "gcj02";
                break;
            case "Baidu":
                zbName = "bd09";
                break;
            case "OSM":
            case "TianDiTu":
                zbName = "wgs84";
                break;
        }
        return zbName;
    }
};

L.GridLayer.include({
    _setZoomTransform: function (level, _center, zoom) {
        var center = _center;
        if (center != undefined && this.options) {
            if (this.options.coordType == 'gcj02') {
                center = L.coordConvertor().gps84_To_gcj02(_center.lng, _center.lat);
            } else if (this.options.coordType == 'bd09') {
                center = L.coordConvertor().gps84_To_bd09(_center.lng, _center.lat);
            }
        }
        var scale = this._map.getZoomScale(zoom, level.zoom),
            translate = level.origin.multiplyBy(scale)
                .subtract(this._map._getNewPixelOrigin(center, zoom)).round();

        if (L.Browser.any3d) {
            L.DomUtil.setTransform(level.el, translate, scale);
        } else {
            L.DomUtil.setPosition(level.el, translate);
        }
    },
    _getTiledPixelBounds: function (_center) {
        var center = _center;
        if (center != undefined && this.options) {
            if (this.options.coordType == 'gcj02') {
                center = L.coordConvertor().gps84_To_gcj02(_center.lng, _center.lat);
            } else if (this.options.coordType == 'bd09') {
                center = L.coordConvertor().gps84_To_bd09(_center.lng, _center.lat);
            }
        }
        var map = this._map,
            mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
            scale = map.getZoomScale(mapZoom, this._tileZoom),
            pixelCenter = map.project(center, this._tileZoom).floor(),
            halfSize = map.getSize().divideBy(scale * 2);

        return new L.Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
    }
});
View Code

Demo主要代码: 

index.html代码:

Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第3张Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第4张
<!DOCTYPE html>
<html>

<head>
    <title>Leaflet</title>

    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="libs/leaflet/leaflet.css">
    <link rel="stylesheet" href="css/index.css">

    <script type="text/javascript" src="libs/jquery-1.9.1.js"></script>
    <script type="text/javascript" src="libs/leaflet/leaflet-src.js"></script>
    <script type="text/javascript" src="libs/leaflet-plugins/proj4-compressed.js"></script>
    <script type="text/javascript" src="libs/leaflet-plugins/proj4leaflet.js"></script>
    <script type="text/javascript" src="libs/leaflet-plugins/leaflet.baidu.js"></script>
    <script type="text/javascript" src="libs/leaflet-plugins/leaflet.ChineseTmsProviders.js"></script>
    <script type="text/javascript" src="libs/leaflet-plugins/leaflet.mapCorrection.js"></script>
</head>

<body>
    <div id="map" style="cursor:default;"></div>
    <div id="mouseposition"></div>
    <div id="mapzoom"></div>
    <!-- 用于显示调试信息 -->
    <div
        style="display:none; position:absolute; right:0; bottom:30px; background-color:transparent; 1000px; height:30px; margin-right:3px; z-index:99999; border:solid 1px transparent;">
        <input type="text" id="msg" value=""
            style="990px; font-size:12px; padding-left:3px; padding-right:3px; " />
    </div>
    <div
        style="display:none; position:absolute; left:20px; top:20px; background-color:transparent; 1200px; height:30px; z-index:99998; border:solid 1px transparent;">
        <input type="button" onclick="alert('1')" value="测试按钮" />
    </div>
    <script type="text/javascript" src="config/config.js"></script>
    <script type="module" src="js/index.js"></script>
</body>

</html>
View Code

index.js代码:

Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第5张Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第6张
import { Map } from './map.js'
import { Marker } from './marker.js'

let map = new Map(tileUrl, {
    centerLatLng: L.latLng(31.81880456, 117.18087366),
    mapBounds: L.latLngBounds(L.latLng(31.0, 116.6), L.latLng(32.6, 117.8))
});

let marker = new Marker(117.18087366, 31.81880456, {
    id: 1,
    name: '测试marker'
});

map.deviceLayer.addLayer(marker.marker);
View Code

map.js代码:

代码中 new L.TileLayer 时,添加属性 coordType: 'gcj02' ,即可实现高德地图瓦片偏移的纠偏

如果是百度地图瓦片,则添加属性 coordType: 'bd09' 即可

Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第7张Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第8张
/**
 * 地图
 */
class Map {

    map
    deviceLayer = L.layerGroup()

    options = {
        // L.latLng
        centerLatLng: undefined,

        // L.latLngBounds
        mapBounds: undefined
    }

    constructor(tileUrl, options) {

        Object.assign(this.options, options);

        let tileLayer = new L.TileLayer(tileUrl, {
            minZoom: 8,
            maxZoom: 18,
            coordType: 'gcj02'
        });

        this.map = new L.Map('map', {
            center: this.options.centerLatLng,
            zoom: 12,
            minZoom: 8,
            maxZoom: 18,
            maxBounds: this.options.mapBounds,
            layers: [tileLayer],
            attributionControl: false,
            doubleClickZoom: false,
            zoomControl: false
        });

        this.map.addLayer(this.deviceLayer); //设备图层

        L.control.scale().addTo(this.map); //比例尺

        //显示经纬度和地图层级
        let this_ = this;
        this.map.addEventListener("mousemove", function (e) {
            this_.showMousePosition(e);
            this_.showMapZoom();
        });
        this.map.addEventListener("zoomend", function (e) {
            this_.showMapZoom();
        });
    }

    showMousePosition(e) {
        if (!this.mousePositionDiv) {
            this.mousePositionDiv = $('#mouseposition');
        }
        this.mousePositionDiv.text(e.latlng.lng.toFixed(8) + ", " + e.latlng.lat.toFixed(8));
    }

    showMapZoom() {
        if (!this.mapZoomDiv) {
            this.mapZoomDiv = $('#mapzoom');
        }
        this.mapZoomDiv.text(this.map.getZoom().toString());
    }
}

export { Map }
View Code

完整Demo代码下载:

地图瓦片纠偏Demo.zip

代码实现的功能:百度、高德离线地图瓦片加载和纠偏

代码使用了ES6模块化开发,必须部署在服务器上才能在浏览器中访问,可以使用IIS或Tomcat部署

效果图:

高德地图:

 Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第9张

百度地图:

Leaflet 百度、高德地图瓦片坐标 偏移 纠偏第10张

参考github:

https://github.com/gisarmory/Leaflet.InternetMapCorrection

免责声明:文章转载自《Leaflet 百度、高德地图瓦片坐标 偏移 纠偏》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇json-patch 了解NodeJS使用npm和cnpm高速下载下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【spring】jdbcTemplate之sql参数注入

demo @Repository("jdbcDao") public class JdbcTemplateDao { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private NamedParameterJdbcTemplate namedTe...

java中年月日的加减法,年月的加减法使用

本文为博主原创,未经允许不得转载: java计算两个年月日之间相差的天数: public static int daysBetween(String smdate,String bdate) throws ParseException{        int daysInterval=0;        if(StringUtils.isNoneBlank...

稍为改写了下DropBrute用于IPV6检测nginx的access_log

#!/bin/sh # # DropBrute.sh @20130516 # # minimalist OpenWRT/dropbear ssh brute force attack banning script # # Installation steps: # # 1) Optionally edit the variables in the head...

JS控制div跳转到指定的位置的解决方案总结

总结一下自己在写这个需求遇到的问题,相信大家应该是经常遇到的。即要求滚轮滚动到指定的位置。先看下基本的解决方案。 1.给链接a加个#的方式来实现跳转。(锚点方法)这里直接贴下代码:    html页面: <div id="container"> <a href="http://t.zoukankan.com/jtjds-...

GSYVideoPlayer 视频播放库

01. 优先介绍一下模拟器中没有声音的问题: 官方Demo中的内容较多,我这边按照自己的需求,做了个小DEMO,便于后期引用学习 ----------------------------------------- 02. 依赖配置       1 //视频播放 2 implementation 'com.shuyu:GSYVideoPla...

js中实现高德地图坐标经纬度转百度地图坐标

1 function tobdMap(x, y) { 2 var x_pi = 3.14159265358979324 * 3000.0 / 180.0; 3 var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); 4...