分享proj4js中經緯度和蘭伯特投影的轉換代碼

2021-01-16 技術幾句雜談

引言

蘭伯特投影在氣象數據的處理中,是比較常用的投影坐標系,根據不同區域、範圍進行投影。

proj4是專業的坐標轉換類庫,有各種語言版本的,C++,java,js,python版等,可以很方便的將坐標從一個坐標系轉換到另一個坐標系。在前端使用的時候,應用場景需要轉換大量的坐標,就會發現使用proj4js存在性能問題,查看了一下proj4js的原始碼,發現類庫每次調用初始化很多不相關的類型,對象等,所以,在基礎上,進行了提取。


轉換代碼及說明

//初始化常用的變量,直接換算成弧度,提升計算性能

var EPSLN = (typeof Number.EPSILON === 'undefined') ? 1.0e-10 : Number.EPSILON;

var conv = 180 / Math.PI;

var HALF_PI = Math.PI / 2;

var SPI = 3.14159265359;

var TWO_PI = 2 * Math.PI;

var a = 6378137;

var b = 6356752.314245179;

var e = 0.08181919084262157;

var lat1 = 0.52359877559829;

var lat2 = 1.04719755119659; 

var long0 = 1.8029251173101;

var lat0 = 0;

var k0 = 1; 

var ns;

var f0;

var rh;

//常用的轉換參數,直接提取引用

var tsfnz = function(eccent, phi, sinphi) {

 var con = eccent * sinphi;

 var com = 0.5 * eccent;

 con = Math.pow(((1 - con) / (1 + con)), com);

 return(Math.tan(0.5 * (HALF_PI - phi)) / con);

 };

var sign = function(x) {

 return x < 0 ? -1 : 1;

 };

 var msfnz = function(eccent, sinphi, cosphi) {

 var con = eccent * sinphi;

 return cosphi / (Math.sqrt(1 - con * con));

 };

var adjust_lon = function(x) {

return(Math.abs(x) <= SPI) ? x : (x - (sign(x) * TWO_PI));

 };

var phi2z = function(eccent, ts) {

var eccnth = 0.5 * eccent;

var con, dphi;

var phi = HALF_PI - 2 * Math.atan(ts);

for(var i = 0; i <= 15; i++) {

con = eccent * Math.sin(phi);

dphi = HALF_PI - 2 * Math.atan(ts * (Math.pow(((1 - con) / (1 + con)), eccnth))) - phi;

phi += dphi;

if(Math.abs(dphi) <= 0.0000000001) {

  return phi;

 }

}

return -9999;

};     

//根據proj4的坐標系描述字符串,解析其中的參數

function init(prjstr) {

if(prjstr.indexOf(" ") > -1) {

var _prjArr = prjstr.split(" ");

_prjArr.forEach(function(item, index, input) {

if(item.indexOf("lat_0") > -1) {

 lat0 = parseFloat(item.split("=")[1]) / conv;

 }

 })

 }

var sin1 = Math.sin(lat1);

var cos1 = Math.cos(lat1);

var ms1 = msfnz(e, sin1, cos1);

var ts1 = tsfnz(e, lat1, sin1);

var sin2 = Math.sin(lat2);

var cos2 = Math.cos(lat2);

var ms2 = msfnz(e, sin2, cos2);

var ts2 = tsfnz(e, lat2, sin2);

var ts0 = tsfnz(e, lat0, Math.sin(lat0));

if(Math.abs(lat1 - lat2) > EPSLN) {

 ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2);

 } else {

   ns = sin1;

 }

if(isNaN(ns)) {

  ns = sin1;

 }

f0 = ms1 / (ns * Math.pow(ts1, ns));

rh = a * f0 * Math.pow(ts0, ns);

}    

//經緯度坐標轉換蘭伯特坐標

function projCood(lon, lat) {

lon = lon / conv;

lat = lat / conv;

if(Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) {

lat = sign(lat) * (HALF_PI - 2 * EPSLN);

}

var con = Math.abs(Math.abs(lat) - HALF_PI);

 var ts, rh1;

 if(con > EPSLN) {

 ts = tsfnz(e, lat, Math.sin(lat));

rh1 = a * f0 * Math.pow(ts, ns);

} else {

 con = lat * ns;

  if(con <= 0) {

   return null;

   }

rh1 = 0;

 }

var theta = ns * adjust_lon(lon - long0);

var nlon = (rh1 * Math.sin(theta));

var nlat = (rh - rh1 * Math.cos(theta));

 return [nlon, nlat];

 }

 //蘭伯特坐標轉經緯度坐標

function inverseProj(x1, y1) {

var rh1, con, ts;

var lat, lon;

var x = x1 / k0;

var y = (rh - y1 / k0);

if(ns > 0) {

rh1 = Math.sqrt(x * x + y * y);

con = 1;

} else {

rh1 = -Math.sqrt(x * x + y * y);

con = -1;

 }

var theta = 0;

if(rh1 !== 0) {

theta = Math.atan2((con * x), (con * y));

  }

if((rh1 !== 0) || (ns > 0)) {

 con = 1 / ns;

 ts = Math.pow((rh1 / (a * f0)), con);

lat = phi2z(e, ts);

if(lat === -9999) {

return null;

 }

 } else {

  lat = -HALF_PI;

}

 lon = adjust_lon(theta / ns + long0);

 return [lon * conv, conv * lat];

 }


對於在應用中的其他坐標系轉換,同樣能夠在其中進行代碼提取。

相關焦點

  • Python蘭伯特投影中國區域等值線圖(含南海小地圖)
    np.linspace(15, 55, 60)nlon, nlat = np.meshgrid(nlon, nlat)func = Rbf(olon, olat, stid_data, function='linear')stid_pre = func(nlon, nlat)# 地圖area_str = ["China"]shp_add=r'F:/RMeteoInfo/data/map/bou2_4l.shp'shp_mask
  • 已知經緯度計算兩點間地理距離
    本文參考比利時天文學家Jean Meeus (1991)的《天文算法》81-86頁的公式,給出相應的R代碼。 將經緯度的度、分、秒轉換為十進位定義函數deg2dec完成這一轉換:deg2dec <- function(h,m,s){ if(h < 0){ m = - m s = -s } res = h + m/60 + s/3600 return(res)}
  • ArcGIS坐標轉換及投影詳解
    地理數據的坐標主要分為兩種方式:地理坐標和投影坐標。地理坐標是球面坐標,簡單來說就是使用經緯度來表示位置坐標,投影是按照一定的數學模型將球面坐標投影到幾何體後,用平面坐標(x和y)來表示位置信息。工作中我們經常會用到地理坐標與投影坐標的轉換。
  • 經緯度WGS84地理坐標系轉換成CGCS2000坐標系步驟.docx
    經緯度WGS84地理坐標系轉換成CGCS2000坐標系步驟 基於ArcGIS中進行操作 供大家參考學習 文末有該文檔的下載方式 1、 將圖層從奧維中導出成shp文件,
  • 【小技巧】小數點的經緯度與度分秒的經緯度轉換
    某年月日,羅女士讓善子幫忙把小數形式的經緯度轉換為度分秒形式的經緯度,結果,善子卻犯了嚴重的錯誤!在此向羅女士表示深深的歉意。 工作中,我們有時會遇到需要將小數點形式的經緯度轉換為度分秒形式的經緯度,但稍有不慎,就會出錯。 俗話說:差之毫厘謬以千裡。
  • 經緯度、平面坐標系轉換方法
    使用工具:經緯度與我國54、80大地坐標轉換的小工具我們經常需要進行坐標系之間、經緯度和XY之間的轉換,我們使用這個小工具,做一個介紹
  • 經緯度轉換54坐標系
    經緯度轉換54坐標系
  • 前端工程化以及如何通過Node.js中babel來編譯es6模塊化代碼
    模塊化就是把單獨的一個功能封裝到一個模塊(文件)中,模塊之間相互隔離,但是可以通過特定的接口公開內部成員,也可以依賴別的模塊模塊化開發的好處:方便代碼的重用,從而提升開發效率,並且方便後期的維護一開始模塊化規範有哪些?
  • 你在小程序中怎麼計算兩個經緯度的距離?
    有了官方支持時的調用在沒有官方支持時,小程序中的位置獲取,可以採用騰訊地圖,高德地圖,百度地圖都可以,但是你需要先通過小程序的wx.getLocation 獲取當前的經緯度,然後再藉助第三方地圖提供的webservice API ,自己在後端實現一個根據經緯度獲取當前位置的接口,然後供小程序調用。
  • 乾貨|最詳細的GIS中坐標系講解
    在第三部分,是實際操作過程中遇到的種種問題,如投影不對會出現什麼情況、如何轉換GCS、如何切換PCS(重投影問題)等問題,涉及一些數學轉換的思維,需要有一定的空間想像能力。在第四部分,我簡單介紹一下所謂的火星坐標。
  • 「原創」如何高效管理你的js代碼
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫1.為什麼需要管理好js代碼1.1 你有遇到這些情況嗎其他項目使用自己慢慢豐富的工具類,你是copy過去的?難免需要刪除整個node_modules並重裝依賴庫,你會因為重寫過某些庫的代碼而糾結?
  • 和大家分享JS編程知識之JS內置對象實例詳解
    大家好,本次和給大家分享JS的內置對象。本次主要是通過實例來和大家一起分享學習,分享學習什麼是對象,以及String字符串對象,Data日期對象,Array數組對象,Math對象的常用方法的使用。字符串indexOf的用法3、match():內容匹配,示例代碼如下:該實例通過match()方法用World在字符串Hello World中進行匹配,輸出結果是World,如果World在字符串中不存子,
  • 從Rust到遠方:ASM.js星系
    注意這裡因為考慮了老瀏覽器如IE,所以代碼需要一點小小的轉換來優化和精簡ASM.js模塊,我們用uglify-es工具,如下:$ $ sed -i '' '1s/^/function GUTENBERG_POST_PARSER_ASM_MODULE() {/; s/export //' gutenberg_post_parser.asm.js$ echo 'return
  • ArcGIS坐標系統與投影變換學習筆記
    基準面和長短軸三個要素來定義了北京54地理坐標的基準面。自定義坐標系:需要自定義橢球體的基準面、長短半軸。大家可以自己在ArcGis Arcpy中編寫程序查看你的軟體中有幾個坐標系,我的編譯出來是698個,和視頻中的727個還是有差別。這可能把自己定義的坐標系也算進去了。我的這個電腦軟體不常辦公,沒有自定義的坐標。
  • 4種可用於組織大型Vue.js項目的最佳實踐
    因此,本文將討論4種可用於組織大型Vue.js項目的最佳實踐。1.使用Vue Slots使代碼易於理解父子關係是組件之間相互連接的最常用方法之一,但有時這可能並不是最佳選擇。想像一下,如果出現在單個父組件中有大量子組件的情況,那麼可能就不得不使用大量道具和發出事件來處理這些子組件,很快一切會變得一團糟。
  • 前端小知識——地圖坐標轉換
    ,就是經度(longitude)和維度(latitude)分別給對應X,Y中的誰?來看看上面的圖:經緯度大家都知道,地球上橫線是緯度,縱線是經度。這也導致了我們下意識就會覺得,橫線是X,縱線是Y。這樣的認知顯然是錯誤的。但其實,橫線是刻畫了Y軸上的刻度,縱線是刻畫了X軸上的刻度,這裡要用到投影的角度來看問題。
  • Angular、React 當前,Vue.js 優劣幾何?
    2019 更是熱度不減,而作為近年來尤為熱門的前端框架,Vue.js 自是積累了大量關注。那麼,Vue.js 是適合你的框架嗎?作者 |Tim Han譯者 | 蘇本如責編 | 仲培藝以下為譯文:對於大多數人來說,現在要構建一個新的前端應用,對框架/庫的選擇在很大程度上都是在 Angular 和 React 中二選一。
  • 使用reveal.js製作精美的網頁版PPT
    本文轉載自【微信公眾號:趣談前端,ID:beautifulFront】經微信公眾號授權轉載,如需轉載與原文作者聯繫最近在做季度總結和技術分享,所以需要做個PPT, 來回顧這半年來的技術貢獻.reveal.js可以把 Markdown 文件轉為類似 PPT 的演示文稿,輕快省力,減少排版上的時間,讓演講者更專於文字內容;同時,也獲得 PPT 所不具有的靈活性製作發布靈活、不限應用,不限平臺, 只需修改或打開 HTML 文件豐富的特性,支持過渡動畫、代碼高亮、視頻背景、Markdown 語法、導出 PDF 等極度輕量,佔用空間和內存少說了這麼多revealjs的優點,接下來我們就來學習如何使用它吧
  • 從零開始GIS(Ⅴ)— 投影
    本篇將掰扯一下投影坐標系的七七八八,希望對你有所幫助。地圖投影就是將一個三維曲面即地球球面轉換到一個二維平面上,無論什麼投影方式,變形都是無法避免的,所以地圖編制人員需要根據地圖範圍和應用場景的不同,採用不同的投影方式,來儘可能地降低投影變形帶來的誤差。在人們不斷應用摸索過程中,誕生了很多種投影方法。
  • ArcGIS將Excel經緯度數據轉換為shp點數據
    一、操作準備 1.1 軟體 ArcMap10.4.1 1.2 數據 excel數據(全國機場點數據.xls) ★excel數據中要含有經緯度。