赞
踩
一、环境配置
安装百度地图
vue3命令
npm install vue-baidu-map-3x --save --force
vue2命令
npm install vue-baidu-map --save --force
安装openlayers
npm install ol --save --force
二、获取百度地图ak
参考文章:vue3使用百度地图(详)-CSDN博客
三、代码
1、main.js
下面的 ak 对应百度地图中申请的 ak。
- import {createApp} from 'vue'
- import App from './App.vue'
- import BaiduMap from "vue-baidu-map-3x";
-
- const app = createApp(App)
- app.use(BaiduMap, {ak: 'N6xGBXTyDimGbbbbFfyZY6eCWDTGGiG'})
- app.mount('#app')
单独测试百度地图:
- <template>
- <baidu-map
- class="map"
- :center="mapCenter"
- :zoom="mapZoom"
- :scroll-wheel-zoom="true"
- @ready="onMapReady">
- </baidu-map>
- </template>
-
- <script>
- export default {
- name: "BaiduMapTest",
- data() {
- return {
- mapCenter: {lng: 116.405706, lat: 39.915599},
- mapZoom: 15,
- map: null,
- }
- },
- methods: {
- /**
- * @Event 方法
- * @description: 获取地图实例,并添加事件监听器
- * */
- onMapReady(map) {
- this.map = map.map;
- },
- }
- }
- </script>
-
- <style scoped>
-
- .map {
- width: 100%;
- height: 100vh;
- }
- </style>
测试结果:
2、MapOpenlayers.vue
ask:为什么能无偏差? ans:定义百度投影,这是实现无偏移加载百度地图离线瓦片核心所在。网上很多相关资料在用OpenLayers加载百度地图离线瓦片时都认为投影就是EPSG:3857(也就是Web墨卡托投影)。事实上这是错误的,因此无法做到无偏移加载。百度地图有自己独特的投影体系,必须在OpenLayers中自定义百度投影,才能实现无偏移加载。百度投影实现的核心文件为bd09.js,在迈高图官网可以找到查看这个文件。
ask:为什么不能使用XYZ? ans:加载百度地图离线瓦片不能用ol.source.XYZ,ol.source.XYZ针对谷歌地图(注意:是谷歌地图)而设计,而百度地图与谷歌地图使用了不同的投影、分辨率和瓦片网格。因此这里使用ol.source.TileImage来自行指定投影、分辨率、瓦片网格。 (注:XYZ: 用于具有URL模板中定义的一组XYZ格式的URL的tile数据)
- <template>
- <div id="app">
- <div id="map" style="width: 100%;height: 1000px"></div>
- </div>
- </template>
- <script>
- import { Map, View } from 'ol'// 地图实例方法、视图方法
- import Tile from 'ol/layer/Tile'// 瓦片渲染方法
- import 'ol/ol.css'
- import {onMounted, ref} from "vue";
- import {TileGrid} from "ol/tilegrid";
- import {TileImage} from "ol/source";
- import {addCoordinateTransforms, addProjection, Projection, transform} from "ol/proj";
- import {lngLatToMercator, mercatorToLngLat} from "@/utils/bd09";
- export default {
- name: "map_openlayers",
- setup () {
- const map = ref()
- const initMap = () => {
- /*定义百度投影,这是实现无偏移加载百度地图离线瓦片核心所在。
- 网上很多相关资料在用OpenLayers加载百度地图离线瓦片时都认为投影就是EPSG:3857(也就是Web墨卡托投影)。
- 事实上这是错误的,因此无法做到无偏移加载。
- 百度地图有自己独特的投影体系,必须在OpenLayers中自定义百度投影,才能实现无偏移加载。
- 百度投影实现的核心文件为bd09.js,在迈高图官网可以找到查看这个文件。*/
- let projBD09 = new Projection({
- code: 'BD:09',
- extent: [-20037726.37, -11708041.66, 20037726.37, 12474104.17],
- units: 'm',
- axisOrientation: 'neu',
- global: false
- });
-
- addProjection(projBD09);
- addCoordinateTransforms("EPSG:4326", "BD:09",
- function (coordinate) {
- // eslint-disable-next-line no-undef
- return lngLatToMercator(coordinate);
- },
- function (coordinate) {
- // eslint-disable-next-line no-undef
- return mercatorToLngLat(coordinate);
- }
- );
-
- /*定义百度地图分辨率与瓦片网格*/
- let resolutions = [];
- for (let i = 0; i <= 18; i++) {
- resolutions[i] = Math.pow(2, 18 - i);
- }
-
- let tilegrid = new TileGrid({
- origin: [0, 0],
- resolutions: resolutions
- });
-
- /*加载百度地图离线瓦片不能用ol.source.XYZ,ol.source.XYZ针对谷歌地图(注意:是谷歌地图)而设计,
- 而百度地图与谷歌地图使用了不同的投影、分辨率和瓦片网格。因此这里使用ol.source.TileImage来自行指定
- 投影、分辨率、瓦片网格。*/
- let baidu_source = new TileImage({
- projection: "BD:09",//投影类型
- tileGrid: tilegrid,
- tileUrlFunction: function (tileCoord) {
- if (!tileCoord) return "";
- let z = tileCoord[0];
- let x = tileCoord[1];
- let y = tileCoord[2];
- // 对编号xy处理
- let baiduX;
- baiduX = x < 0 ? x : "M" + -x;
- let baiduY;
- baiduY = -y;
- return (
- "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" +
- baiduX +
- "&y=" +
- baiduY +
- "&z=" +
- z +
- "&styles=pl&udt=20151021&scaler=1&p=1"
- );
- },
- });
-
- let baidu_layer = new Tile({
- source: baidu_source
- });
-
- new Map({
- layers: [baidu_layer],
- view: new View({
- //https://api.map.baidu.com/lbsapi/getpoint/index.html
- //(利用百度的坐标拾取器获取坐标,在下面设置中心坐标点的经纬度并转换)
- center: transform([116.405706,39.915599], 'EPSG:4326', 'BD:09'),
- projection: 'BD:09',
- zoom: 10
- }),
- target: 'map'
- });
- }
-
- onMounted(() => {
- initMap()
- })
- return {
- initMap,
- map
- }
- }
- }
- </script>
-
- <style scoped>
-
- </style>
3、bd09.js
- var MCBAND = [12890594.86, 8362377.87, 5591021, 3481989.83,
- 1678043.12, 0
- ];
- var LLBAND = [75, 60, 45, 30, 15, 0];
- var MC2LL = [
- [1.410526172116255e-8, 0.00000898305509648872, -1.9939833816331, 200.9824383106796, -187.2403703815547, 91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 17337981.2],
- [-7.435856389565537e-9, 0.000008983055097726239, -0.78625201886289, 96.32687599759846, -1.85204757529826, -59.36935905485877,
- 47.40033549296737, -16.50741931063887,
- 2.28786674699375, 10260144.86
- ],
- [-3.030883460898826e-8, 0.00000898305509983578,
- 0.30071316287616, 59.74293618442277,
- 7.357984074871, -25.38371002664745,
- 13.45380521110908, -3.29883767235584,
- 0.32710905363475, 6856817.37
- ],
- [-1.981981304930552e-8, 0.000008983055099779535,
- 0.03278182852591, 40.31678527705744,
- 0.65659298677277, -4.44255534477492,
- 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06
- ],
- [3.09191371068437e-9, 0.000008983055096812155,
- 0.00006995724062, 23.10934304144901, -0.00023663490511, -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4
- ],
- [2.890871144776878e-9, 0.000008983055095805407, -3.068298e-8, 7.47137025468032, -0.00000353937994, -0.02145144861037, -0.00001234426596, 0.00010322952773, -0.00000323890364, 826088.5]
- ];
-
- var LL2MC = [
- [-0.0015702102444, 111320.7020616939,
- 1704480524535203, -10338987376042340,
- 26112667856603880, -35149669176653700,
- 26595700718403920, -10725012454188240,
- 1800819912950474, 82.5
- ],
- [0.0008277824516172526, 111320.7020463578,
- 647795574.6671607, -4082003173.641316,
- 10774905663.51142, -15171875531.51559,
- 12053065338.62167, -5124939663.577472,
- 913311935.9512032, 67.5
- ],
- [0.00337398766765, 111320.7020202162,
- 4481351.045890365, -23393751.19931662,
- 79682215.47186455, -115964993.2797253,
- 97236711.15602145, -43661946.33752821,
- 8477230.501135234, 52.5
- ],
- [0.00220636496208, 111320.7020209128,
- 51751.86112841131, 3796837.749470245,
- 992013.7397791013, -1221952.21711287,
- 1340652.697009075, -620943.6990984312,
- 144416.9293806241, 37.5
- ],
- [-0.0003441963504368392, 111320.7020576856,
- 278.2353980772752, 2485758.690035394,
- 6070.750963243378, 54821.18345352118,
- 9540.606633304236, -2710.55326746645,
- 1405.483844121726, 22.5
- ],
- [-0.0003218135878613132, 111320.7020701615,
- 0.00369383431289, 823725.6402795718,
- 0.46104986909093, 2351.343141331292,
- 1.58060784298199, 8.77738589078284,
- 0.37238884252424, 7.45
- ]
- ];
-
- // eslint-disable-next-line no-unused-vars
- export function lngLatToMercator(T) {
- var c = new cd(T[0], T[1]);
- var r = convertLL2MC(c);
- return [r.lng, r.lat];
- }
-
- // eslint-disable-next-line no-unused-vars
- export function mercatorToLngLat(T) {
- var c = new cd(T[0], T[1]);
- var r = convertMC2LL(c);
- return [r.lng, r.lat];
- }
-
- function convertLL2MC(T) {
- var cL, cN;
- T.lng = getLoop(T.lng, -180, 180);
- T.lat = getRange(T.lat, -74, 74);
- cL = new cd(T.lng, T.lat);
- for(var cM = 0; cM < LLBAND.length; cM++) {
- if(cL.lat >= LLBAND[cM]) {
- cN = LL2MC[cM];
- break
- }
- }
- if(!cN) {
- for(var cM = LLBAND.length - 1; cM >= 0; cM--) {
- if(cL.lat <= -LLBAND[cM]) {
- cN = LL2MC[cM];
- break
- }
- }
- }
- var cO = convertor(T, cN);
- var T = new cd(cO.lng.toFixed(2), cO.lat.toFixed(2));
- return T
- }
-
- function convertMC2LL(cL) {
- var cM, cO;
- cM = new cd(Math.abs(cL.lng), Math.abs(cL.lat));
- for(var cN = 0; cN < MCBAND.length; cN++) {
- if(cM.lat >= MCBAND[cN]) {
- cO = MC2LL[cN];
- break
- }
- }
- var T = convertor(cL, cO);
- var cL = new cd(T.lng.toFixed(6), T.lat.toFixed(6));
- return cL
- }
-
- function getRange(cM, cL, T) {
- if(cL != null) {
- cM = Math.max(cM, cL)
- }
- if(T != null) {
- cM = Math.min(cM, T)
- }
- return cM
- }
-
- function getLoop(cM, cL, T) {
- while(cM > T) {
- cM -= T - cL
- }
- while(cM < cL) {
- cM += T - cL
- }
- return cM
- }
-
- function convertor(cM, cN) {
- if(!cM || !cN) {
- return
- }
- var T = cN[0] + cN[1] * Math.abs(cM.lng);
- var cL = Math.abs(cM.lat) / cN[9];
- var cO = cN[2] + cN[3] * cL + cN[4] * cL * cL + cN[5] * cL *
- cL * cL + cN[6] * cL * cL * cL * cL + cN[7] * cL *
- cL * cL * cL * cL + cN[8] * cL * cL * cL * cL *
- cL * cL;
- T *= (cM.lng < 0 ? -1 : 1);
- cO *= (cM.lat < 0 ? -1 : 1);
- return new cd(T, cO)
- }
-
- function cd(T, cL) {
- if(isNaN(T)) {
- T = bV(T);
- T = isNaN(T) ? 0 : T
- }
- if(b3(T)) {
- T = parseFloat(T)
- }
- if(isNaN(cL)) {
- cL = bV(cL);
- cL = isNaN(cL) ? 0 : cL
- }
- if(b3(cL)) {
- cL = parseFloat(cL)
- }
- this.lng = T;
- this.lat = cL
- }
- cd.isInRange = function(T) {
- return T && T.lng <= 180 && T.lng >= -180 && T.lat <= 74 &&
- T.lat >= -74
- };
- cd.prototype.equals = function(T) {
- return T && lat == T.lat && lng == T.lng
- };
-
- function bV(cN) {
- var cL = "";
- var cU, cS, cQ = "";
- var cT, cR, cP, cO = "";
- var cM = 0;
- var T = /[^A-Za-z0-9\+\/\=]/g;
- if(!cN || T.exec(cN)) {
- return cN
- }
- cN = cN.replace(/[^A-Za-z0-9\+\/\=]/g, "");
- do {
- cT = cf.indexOf(cN.charAt(cM++));
- cR = cf.indexOf(cN.charAt(cM++));
- cP = cf.indexOf(cN.charAt(cM++));
- cO = cf.indexOf(cN.charAt(cM++));
- cU = (cT << 2) | (cR >> 4);
- cS = ((cR & 15) << 4) | (cP >> 2);
- cQ = ((cP & 3) << 6) | cO;
- cL = cL + String.fromCharCode(cU);
- if(cP != 64) {
- cL = cL + String.fromCharCode(cS)
- }
- if(cO != 64) {
- cL = cL + String.fromCharCode(cQ)
- }
- cU = cS = cQ = "";
- cT = cR = cP = cO = ""
- } while (cM < cN.length);
- return cL
- }
-
- function b3(T) {
- return typeof T == "string"
- }
运行结果截图
如需要定位的话,添加以下方法:
- function searchPoint(_point) {
- _point = tobdMap(_point.split(","));//如果传入的是火星坐标系的话,要转成百度坐标系
- var point = new ol.Feature({geometry:
- new ol.geom.Point(ol.proj.fromLonLat(_point, 'BD:09'))})// 将经纬度转成BD:09投影,此投影需引入bd09.js
- point.setStyle(new ol.style.Style({
- image:new ol.style.Icon({
- anchor: [0.5, 1],
- src:
- basePath + "/img/localpoint.png"
- })
-
- }));
-
- pointSource.clear();
- pointSource.addFeature(point);
- map.setView(new ol.View({
- center:ol.proj.transform(_point, 'EPSG:4326', 'EPSG:3857'),
- zoom:8,
- maxZoom:19
- }));
- };
-
- //火星坐标系转百度坐标系
- function tobdMap(coordinate) {
- let x_pi = 3.14159265358979324 * 3000.0 / 180.0;
- let x = coordinate[0];
- let y = coordinate[1];
- let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
- let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
- let lngs = z * Math.cos(theta) + 0.0065;
- let lats = z * Math.sin(theta) + 0.006;
- let zb=[];
- zb[0]=lngs;
- zb[1]=lats;
- return zb;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。