JS不同地圖坐標(biāo)系經(jīng)緯度轉(zhuǎn)換方法(天地圖、高德地圖、百度地圖、騰訊地圖)
問(wèn)題:坐標(biāo)點(diǎn)在不同的地圖上會(huì)出現(xiàn)偏差顯示
地圖:以天地圖,高德地圖作為示例;區(qū)域:以石河子市政府作為示例
提供示例坐標(biāo)點(diǎn) (天地圖獲取的坐標(biāo)點(diǎn)):
let points = [
{lat: 44.30248, lng: 86.07269},
{lat: 44.30545, lng: 86.07273},
{lat: 44.30542, lng: 86.08262},
{lat: 44.30238, lng: 86.08258},
{lat: 44.30295, lng: 86.08091},
{lat: 44.30327, lng: 86.0791},
{lat: 44.30336, lng: 86.0773},
{lat: 44.30321, lng: 86.07552},
{lat: 44.30291, lng: 86.074}]
天地圖展示情況:

高德地圖展示情況:

原因:各個(gè)地圖的坐標(biāo)系不同,需要轉(zhuǎn)換
- WGS-84:是國(guó)際標(biāo)準(zhǔn),GPS坐標(biāo)(Google Earth使用、或者GPS模塊、天地圖)
- GCJ-02:中國(guó)坐標(biāo)偏移標(biāo)準(zhǔn),Google Map、高德、騰訊使用
- BD-09:百度坐標(biāo)偏移標(biāo)準(zhǔn),Baidu Map使用
天地圖轉(zhuǎn)換為高德地圖(即 WGS-84 轉(zhuǎn) GCJ-02):
<script>
import {wgs_gcj_encrypts} from "/@/views/backend/shi/components/common_fun.js";
export default {
methods: {
// 初始化地圖
initAMap() {
。。。。// 初始化地圖的相關(guān)代碼
const pointt = [
{lat: 44.30248, lng: 86.07269},
{lat: 44.30545, lng: 86.07273},
{lat: 44.30542, lng: 86.08262},
{lat: 44.30238, lng: 86.08258},
{lat: 44.30295, lng: 86.08091},
{lat: 44.30327, lng: 86.0791},
{lat: 44.30336, lng: 86.0773},
{lat: 44.30321, lng: 86.07552},
{lat: 44.30291, lng: 86.074}]
let pointts = []
for (const item of wgs_gcj_encrypts(pointt)) {
pointts.push(new AMap.LngLat(item.lng, item.lat))
}
//創(chuàng)建多邊形 Polygon 實(shí)例
const polygon = new AMap.Polygon({
path: pointts, //路徑
fillColor: "rgba(255, 128, 0,0.8)", //多邊形填充顏色
strokeWeight: 2, //線條寬度,默認(rèn)為 2
strokeColor: "rgb(255, 128, 0)", //線條顏色
});
//多邊形 Polygon對(duì)象添加到 Map
this.map.add(polygon);
。。。。
}
}
}
</script>
(復(fù)制可直接使用,將獲取到的坐標(biāo)數(shù)組或?qū)⒁延械淖鴺?biāo)數(shù)組傳過(guò)來(lái),也可傳入單獨(dú)的坐標(biāo)點(diǎn)需要改一下參數(shù)即可)
公共方法文件:(各個(gè)地圖之間的轉(zhuǎn)換方法都有哈)
寫(xiě)法一:(該寫(xiě)法用到的數(shù)據(jù)是一個(gè)面,存在很多點(diǎn)位,使用了循環(huán))
//轉(zhuǎn)換常數(shù)
const x_pi = 3.14159265358979324 * 3000.0 / 180.0
const pi = 3.14159265358979324
const a = 6378245.0
const ee = 0.00669342162296594323
function transformLon(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;
}
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;
}
// 判斷是否在國(guó)內(nèi)
function outOfChina(lat, lon) {
if (lon < 72.004 || lon > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
}
/*
WGS-84轉(zhuǎn)換GCJ-02
(即 天地圖轉(zhuǎn)高德、騰訊地圖)
*/
export const wgs_gcj_encrypts = (latlons) => {
var point = [];
for (const latlon of latlons) {
if (outOfChina(latlon.lat, latlon.lng)) {
point.push({
lat: latlon.lat,
lng: latlon.lng
})
return point;
}
var dLat = transformLat(latlon.lng - 105.0, latlon.lat - 35.0);
var dLon = transformLon(latlon.lng - 105.0, latlon.lat - 35.0);
var radLat = latlon.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);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
var lat = latlon.lat + dLat;
var lng = latlon.lng + dLon;
point.push({
lat: lat,
lng: lng
})
}
return point;
}
/*
BD-09轉(zhuǎn)換GCJ-02
(即 百度轉(zhuǎn)高德、騰訊地圖)
*/
export const bd_google_encrypt = (latlons) => {
var point = [];
for (const latlon of latlons) {
var x = latlon.lng - 0.0065;
var y = latlon.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_lon = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
point.push({
lat: gg_lon,
lng: gg_lat
})
}
return point;
}
/*
GCJ-02轉(zhuǎn)換BD-09
(即 高德、騰訊轉(zhuǎn)百度地圖)
*/
export const google_bd_encrypt = (latlons) => {
var point = [];
for (const latlon of latlons) {
var x = latlon.lng;
var y = latlon.lat;
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_lon = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
point.push({
lat: bd_lat,
lng: bd_lon
})
}
return point;
}
/*
GCJ-02 到 WGS-84 的轉(zhuǎn)換
(即 高德、騰訊轉(zhuǎn)天地圖)
*/
export const gcj_wgs_encrypts = (latlons) => {
var point = [];
for (const latlon of latlons) {
if (outOfChina(latlon.lat, latlon.lng)) {
point.push({
lat: latlon.lat,
lng: latlon.lng
})
return point;
}
var dLat = transformLat(latlon.lng - 105.0, latlon.lat - 35.0);
var dLon = transformLon(latlon.lng - 105.0, latlon.lat - 35.0);
var radLat = latlon.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);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
var lat = dLat;
var lng = dLon;
point.push({
lat: lat,
lng: lng
})
}
return point;
}
寫(xiě)法二:(該寫(xiě)法用的是一個(gè)點(diǎn))
// BD-09 to GCJ-02
export const bd09togcj02 = (bd_lng, bd_lat) => {
const x = bd_lng - 0.0065;
const y = bd_lat - 0.006;
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * Math.PI);
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * Math.PI);
const gg_lng = z * Math.cos(theta);
const gg_lat = z * Math.sin(theta);
return [gg_lng, gg_lat];
}
// GCJ-02 to WGS84
export const gcj02towgs84 = (lng, lat) => {
const a = 6378245.0;
const ee = 0.00669342162296594323;
const pi = Math.PI;
function transformlat(lng, lat) {
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(
lng));
ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * pi) + 320 * Math.sin(lat * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
function transformlng(lng, lat) {
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * pi) + 40.0 * Math.sin(lng / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * pi) + 300.0 * Math.sin(lng / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
let dlat = transformlat(lng - 105.0, lat - 35.0);
let dlng = transformlng(lng - 105.0, lat - 35.0);
const radlat = lat / 180.0 * pi;
let magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
const sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
const mglat = lat + dlat;
const mglng = lng + dlng;
return [lng * 2 - mglng, lat * 2 - mglat];
}
// WGS84 to GCJ-02
export const wgs84togcj02 = (lng, lat) => {
const a = 6378245.0;
const ee = 0.00669342162296594323;
const pi = Math.PI;
function transformlat(lng, lat) {
let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(
lng));
ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * pi) + 320 * Math.sin(lat * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
function transformlng(lng, lat) {
let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * pi) + 40.0 * Math.sin(lng / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * pi) + 300.0 * Math.sin(lng / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
let dlat = transformlat(lng - 105.0, lat - 35.0);
let dlng = transformlng(lng - 105.0, lat - 35.0);
const radlat = lat / 180.0 * pi;
let magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
const sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
const mglat = lat + dlat;
const mglng = lng + dlng;
return [mglng, mglat];
}
轉(zhuǎn)換后高德地圖的效果展示:

總結(jié)
到此這篇關(guān)于JS不同地圖坐標(biāo)系經(jīng)緯度轉(zhuǎn)換方法的文章就介紹到這了,更多相關(guān)JS不同地圖坐標(biāo)系經(jīng)緯度轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ES6學(xué)習(xí)教程之對(duì)象的擴(kuò)展詳解
這篇文章主要給大家介紹了ES6中對(duì)象擴(kuò)展的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-05-05
layer.open提交子頁(yè)面的form和layedit文本編輯內(nèi)容的方法
今天小編就為大家分享一篇layer.open提交子頁(yè)面的form和layedit文本編輯內(nèi)容的方法,具有好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09
javascript 冒泡排序 正序和倒序?qū)崿F(xiàn)代碼
javascript 冒泡排序 正序和倒序?qū)崿F(xiàn)代碼,需要的朋友可以參考下。2010-12-12
值得分享的Bootstrap Ace模板實(shí)現(xiàn)菜單和Tab頁(yè)效果
這篇文章主要為大家分享了基于Bootstrap Ace模板實(shí)現(xiàn)菜單和Tab頁(yè)效果,感興趣的小伙伴們可以參考一下2015-12-12
js生成隨機(jī)數(shù)(指定范圍)的實(shí)例代碼
下面小編就為大家?guī)?lái)一篇js生成隨機(jī)數(shù)(指定范圍)的實(shí)例代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
調(diào)試Node.JS的輔助工具(NodeWatcher)
Node.JS調(diào)試貌似比較麻煩,每次改完了要重啟一下Node進(jìn)程.GOOGLE上有個(gè)NPM模塊,可以監(jiān)控JS文件的更改,然后自動(dòng)重啟Node.但我下載后在windows里運(yùn)行報(bào)錯(cuò)2012-01-01
JS攜帶參數(shù)實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)功能
這篇文章主要介紹了js攜帶參數(shù)實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn),實(shí)現(xiàn)方法也很簡(jiǎn)單,方式一是跳轉(zhuǎn)路徑攜帶參數(shù),第二種方法是通過(guò)sessionStorage傳遞,需要的朋友可以參考下2022-11-11
JS call()及apply()方法使用實(shí)例匯總
這篇文章主要介紹了JS call()及apply()方法使用實(shí)例匯總,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
理解JavaScript設(shè)計(jì)模式中的建造者模式
這篇文章主要介紹了理解JavaScript設(shè)計(jì)模式中的建造者模式,文章基于JavaScript的相關(guān)資料展開(kāi)箱子內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-04-04

