Created
February 14, 2017 15:29
-
-
Save fcce/e191fccad127b094b64ef61ffc8b72af to your computer and use it in GitHub Desktop.
ruby 版经纬度坐标系转换
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class CoordConvert | |
| class << self | |
| PI = 3.14159265358979324 | |
| X_PI = PI * 3000.0 / 180.0 #圆周率转换量 | |
| ## Krasovsky 1940 | |
| ## a = 6378245.0, 1/f = 298.3 | |
| ## b = a * (1 - f) | |
| ## ee = (a^2 - b^2) / a^2 | |
| A = 6378245.0 #椭球体的长半轴半径 | |
| EE = 0.00669342162296594323 #椭球体的第一偏心率 | |
| def convert(from,to,lng,lat) | |
| if from == 'bd09' && to == 'gcj02' | |
| return bd09_to_gcj02(lng,lat) | |
| elsif from == 'gcj02' && to == 'bd09' | |
| return gcj02_to_db09(lng,lat) | |
| elsif from == 'wgs84' && to == 'gcj02' | |
| return wgs84_to_gcj02(lng,lat) | |
| elsif from == 'gcj02' && to == 'wgs84' | |
| return gcj02_to_wgs84(lng,lat) | |
| else | |
| raise ArgumentError.new "only support 'bd09' to 'gjc', 'gcj02' to 'bd09', 'wgs84' to 'gcj02' and 'gcj02' to 'wgs84' " | |
| end | |
| end | |
| private | |
| def bd09_to_gcj02(lng,lat) | |
| x = lng - 0.0065 | |
| y = lat - 0.006 | |
| z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI) | |
| theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI); | |
| gcj_lng = z * Math.cos(theta); | |
| gcj_lat = z * Math.sin(theta); | |
| return gcj_lng,gcj_lat | |
| end | |
| def gcj02_to_db09(lng,lat) | |
| x = lng | |
| y = lat | |
| z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI) | |
| theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI) | |
| bd_lng = z * Math.cos(theta) + 0.0065 | |
| bd_lat = z * Math.sin(theta) + 0.006 | |
| return bd_lng, bd_lat | |
| end | |
| def wgs84_to_gcj02(lng, lat) | |
| return lng, lat if out_of_china(lng, lat) | |
| d_lat = trans_form_lat(lng - 105.0, lat - 35.0) | |
| d_lng = trans_form_lng(lng - 105.0, lat - 35.0) | |
| rad_lat = lat / 180.0 * PI | |
| magic = Math.sin(rad_lat) | |
| magic = 1 - EE * magic * magic | |
| sqrt_magic = Math.sqrt(magic) | |
| d_lng = (d_lng * 180.0) / (A / sqrt_magic * Math.cos(rad_lat) * PI) | |
| d_lat = (d_lat * 180.0) / ((A * (1 - EE)) / (magic * sqrt_magic) * PI) | |
| gcj_lng = lng + d_lng | |
| gcj_lat = lat + d_lat | |
| return gcj_lng, gcj_lat | |
| end | |
| def gcj02_to_wgs84(lng, lat) | |
| return lng, lat if out_of_china(lng, lat) | |
| d_lat = trans_form_lat(lng - 105.0, lat - 35.0) | |
| d_lng = trans_form_lng(lng - 105.0, lat - 35.0) | |
| rad_lat = lat / 180.0 * PI | |
| magic = Math.sin(rad_lat) | |
| magic = 1 - EE * magic * magic | |
| sqrt_magic = Math.sqrt(magic) | |
| d_lat = (d_lat * 180.0) / ((A * (1 - EE)) / (magic * sqrt_magic) * PI) | |
| d_lng = (d_lng * 180.0) / (A / sqrt_magic * Math.cos(rad_lat) * PI) | |
| wgs_lat = lat + d_lat | |
| wgs_lng = lng + d_lng | |
| return lng * 2 - wgs_lng, lat * 2 - wgs_lat | |
| end | |
| def trans_form_lat(lng, lat) | |
| ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(lng.abs) | |
| 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 | |
| end | |
| def trans_form_lng(lng, lat) | |
| ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(lng.abs) | |
| 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 | |
| end | |
| def out_of_china(lng, lat) | |
| if ((72.0040..137.8347).include? lng) && ((0.8293..55.8271).include? lat) | |
| return true | |
| else | |
| return false | |
| end | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment