谷歌地图离线发布系列之偏移处理(三)纠偏算法

来源:互联网 发布:淘宝直通车开通要求 编辑:程序博客网 时间:2024/05/07 04:50

先上代码,用js实现的纠偏算法:

var pi = 3.14159265358979324;//// Krasovsky 1940//// a = 6378245.0, 1/f = 298.3// b = a * (1 - f)// ee = (a^2 - b^2) / a^2;var a = 6378245.0;var ee = 0.00669342162296594323;function outOfChina(lat, lon){    if (lon < 72.004 || lon > 137.8347)        return 1;    if (lat < 0.8293 || lat > 55.8271)        return 1;    return 0;}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(x > 0 ? x:-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 transformLon(x,y){    var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(x > 0 ? x:-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 transformFromWGSToGCJ(wgLoc){    var mgLoc ={};    mgLoc.lat = 0;    mgLoc.lng = 0;    if (outOfChina(wgLoc.lat, wgLoc.lng))    {        mgLoc = wgLoc;        return mgLoc;    }    var dLat = transformLat(wgLoc.lng - 105.0, wgLoc.lat - 35.0);    var dLon = transformLon(wgLoc.lng - 105.0, wgLoc.lat - 35.0);    var radLat = wgLoc.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);    mgLoc.lat = wgLoc.lat + dLat;    mgLoc.lng = wgLoc.lng + dLon;    return mgLoc;}


参考文章1:http://blog.csdn.net/coolypf/article/details/8686588

WGS-84 到 GCJ-02 的转换(即 GPS 加偏)算法是一个普通青年轻易无法接触到的“公开”的秘密。这个算法的代码在互联网上是公开的,详情请使用 Google 搜索 "wgtochina_lb" 。

整理后的算法代码请参考 https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936 。知道了这个算法之后,就可以离线进行 Google 地图偏移校正,不必像之前那么麻烦。

至于 GCJ-02 到 WGS-84 的转换(即 GPS 纠偏),可以使用二分法。

参考文章2:http://www.zuidaima.com/code/file/1665077235663872.htm?dir=/correct_lat_lon/src/com/hgq/correct/MapFix.java

package com.hgq.correct;
003 
004 
005/**
006 * 经纬度纠偏工具类
007 * [一句话功能简述]<p>
008 * [功能详细描述]<p>
009 * @author PeiYu
010 * @version 1.0, 2012-8-24
011 * @see
012 * @since gframe-v100
013 */
014public class MapFix
015{
016    private double casm_f = 0.0;
017 
018    private double casm_rr = 0.0;
019 
020    private double casm_t1 = 0.0;
021 
022    private double casm_t2 = 0.0;
023 
024    private double casm_x1 = 0.0;
025 
026    private double casm_x2 = 0.0;
027 
028    private double casm_y1 = 0.0;
029 
030    private double casm_y2 = 0.0;
031 
032    private MapFix()
033    {
034        casm_rr = 0.0;
035        casm_t1 = 0.0;
036        casm_t2 = 0.0;
037        casm_x1 = 0.0;
038        casm_y1 = 0.0;
039        casm_x2 = 0.0;
040        casm_y2 = 0.0;
041        casm_f = 0.0;
042    }
043 
044    private static MapFix instance;
045 
046    public static MapFix getInstance()
047    {
048        if (instance == null)
049        {
050            instance = new MapFix();
051        }
052        return instance;
053    }
054 
055    /**
056     * 纠偏
057     * @param x 经度
058     * @param y 纬度
059     * @return [0]纠偏后经度   [1]纠偏后纬度
060     */
061    public double[] fix(double x , double y)
062    {
063        double[] res = new double[2];
064        try
065        {
066            double num = x * 3686400.0;
067            double num2 = y * 3686400.0;
068            double num3 = 0.0;
069            double num4 = 0.0;
070            double num5 = 0.0;
071            MapPoint point = wgtochina_lb(1, (int) num, (int) num2, (int) num5, (int) num3, (int) num4);
072            double num6 = point.getX();
073            double num7 = point.getY();
074            num6 /= 3686400.0;
075            num7 /= 3686400.0;
076            res[0] = num6;
077            res[1] = num7;
078        }
079        catch (Exception ex)
080        {
081            System.out.println(ex);
082        }
083        return res;
084    }
085 
086    private void IniCasm(double w_time , double w_lng , double w_lat)
087    {
088        casm_t1 = w_time;
089        casm_t2 = w_time;
090        double num = (int) (w_time / 0.357);
091        casm_rr = w_time - (num * 0.357);
092        if (w_time == 0.0)
093        {
094            casm_rr = 0.3;
095        }
096        casm_x1 = w_lng;
097        casm_y1 = w_lat;
098        casm_x2 = w_lng;
099        casm_y2 = w_lat;
100        casm_f = 3.0;
101    }
102 
103    private double random_yj()
104    {
105        double num = 314159269.0;
106        double num2 = 453806245.0;
107        casm_rr = (num * casm_rr) + num2;
108        double num3 = (int) (casm_rr / 2.0);
109        casm_rr -= num3 * 2.0;
110        casm_rr /= 2.0;
111        return casm_rr;
112    }
113 
114    private double Transform_jy5(double x , double xx)
115    {
116        double num = 6378245.0;
117        double num2 = 0.00669342;
118        double num3 = Math.sqrt(1.0 - ((num2 * yj_sin2(x * 0.0174532925199433)) * yj_sin2(x * 0.0174532925199433)));
119        return ((xx * 180.0) / (((num / num3) * Math.cos(x * 0.0174532925199433)) * 3.1415926));
120    }
121 
122    private double Transform_jyj5(double x , double yy)
123    {
124        double num = 6378245.0;
125        double num2 = 0.00669342;
126        double d = 1.0 - ((num2 * yj_sin2(x * 0.0174532925199433)) * yj_sin2(x * 0.0174532925199433));
127        double num4 = (num * (1.0 - num2)) / (d * Math.sqrt(d));
128        return ((yy * 180.0) / (num4 * 3.1415926));
129    }
130 
131    private double Transform_yj5(double x , double y)
132    {
133        double num = ((((300.0 + (1.0 * x)) + (2.0 * y)) + ((0.1 * x) * x)) + ((0.1 * x) * y))
134                + (0.1 * Math.sqrt(Math.sqrt(x * x)));
135        num += ((20.0 * yj_sin2(18.849555921538762 * x)) + (20.0 * yj_sin2(6.283185307179588* x))) * 0.6667;
136        num += ((20.0 * yj_sin2(3.141592653589794 * x)) + (40.0 * yj_sin2(1.0471975511965981* x))) * 0.6667;
137        return (num + (((150.0 * yj_sin2(0.26179938779914952 * x)) + (300.0 * yj_sin2(0.10471975511965979 * x))) * 0.6667));
138    }
139 
140    private double Transform_yjy5(double x , double y)
141    {
142        double num = ((((-100.0 + (2.0 * x)) + (3.0 * y)) + ((0.2 * y) * y)) + ((0.1 * x) * y))
143                + (0.2 * Math.sqrt(Math.sqrt(x * x)));
144        num += ((20.0 * yj_sin2(18.849555921538762 * x)) + (20.0 * yj_sin2(6.283185307179588* x))) * 0.6667;
145        num += ((20.0 * yj_sin2(3.141592653589794 * y)) + (40.0 * yj_sin2(1.0471975511965981* y))) * 0.6667;
146        return (num + (((160.0 * yj_sin2(0.26179938779914952 * y)) + (320.0 * yj_sin2(0.10471975511965979 * y))) * 0.6667));
147    }
148 
149    private MapPoint wgtochina_lb(int wg_flag , int wg_lng , int wg_lat , int wg_heit , int wg_week , int wg_time)
150    {
151        MapPoint point = null;
152        if (wg_heit <= 0x1388)
153        {
154            double num = wg_lng;
155            num /= 3686400.0;
156            double x = wg_lat;
157            x /= 3686400.0;
158            if (num < 72.004)
159            {
160                return point;
161            }
162            if (num > 137.8347)
163            {
164                return point;
165            }
166            if (x < 0.8293)
167            {
168                return point;
169            }
170            if (x > 55.8271)
171            {
172                return point;
173            }
174            if (wg_flag == 0)
175            {
176                IniCasm((double) wg_time, (double) wg_lng, (double) wg_lat);
177                point = new MapPoint();
178                point.setLatitude((double) wg_lng);
179                point.setLongitude((double) wg_lat);
180                return point;
181            }
182            casm_t2 = wg_time;
183            double num3 = (casm_t2 - casm_t1) / 1000.0;
184            if (num3 <= 0.0)
185            {
186                casm_t1 = casm_t2;
187                casm_f++;
188                casm_x1 = casm_x2;
189                casm_f++;
190                casm_y1 = casm_y2;
191                casm_f++;
192            }
193            else if (num3 > 120.0)
194            {
195                if (casm_f == 3.0)
196                {
197                    casm_f = 0.0;
198                    casm_x2 = wg_lng;
199                    casm_y2 = wg_lat;
200                    double num4 = casm_x2 - casm_x1;
201                    double num5 = casm_y2 - casm_y1;
202                    double num6 = Math.sqrt((num4 * num4) + (num5 * num5)) / num3;
203                    if (num6 > 3185.0)
204                    {
205                        return point;
206                    }
207                }
208                casm_t1 = casm_t2;
209                casm_f++;
210                casm_x1 = casm_x2;
211                casm_f++;
212                casm_y1 = casm_y2;
213                casm_f++;
214            }
215            double xx = Transform_yj5(num - 105.0, x - 35.0);
216            double yy = Transform_yjy5(num - 105.0, x - 35.0);
217            double num9 = wg_heit;
218            xx = ((xx + (num9 * 0.001)) + yj_sin2(wg_time * 0.0174532925199433)) + random_yj();
219            yy = ((yy + (num9 * 0.001)) + yj_sin2(wg_time * 0.0174532925199433)) + random_yj();
220            point = new MapPoint();
221            point.setX((num + Transform_jy5(x, xx)) * 3686400.0);
222            point.setY((x + Transform_jyj5(x, yy)) * 3686400.0);
223        }
224        return point;
225    }
226 
227    private double yj_sin2(double x)
228    {
229        double num = 0.0;
230        if (x < 0.0)
231        {
232            x = -x;
233            num = 1.0;
234        }
235        int num2 = (int) (x / 6.28318530717959);
236        double num3 = x - (num2 * 6.28318530717959);
237        if (num3 > 3.1415926535897931)
238        {
239            num3 -= 3.1415926535897931;
240            if (num == 1.0)
241            {
242                num = 0.0;
243            }
244            else if (num == 0.0)
245            {
246                num = 1.0;
247            }
248        }
249        x = num3;
250        double num4 = x;
251        double num5 = x;
252        num3 *= num3;
253        num5 *= num3;
254        num4 -= num5 * 0.166666666666667;
255        num5 *= num3;
256        num4 += num5 * 0.00833333333333333;
257        num5 *= num3;
258        num4 -= num5 * 0.000198412698412698;
259        num5 *= num3;
260        num4 += num5 * 2.75573192239859E-06;
261        num5 *= num3;
262        num4 -= num5 * 2.50521083854417E-08;
263        if (num == 1.0)
264        {
265            num4 = -num4;
266        }
267        return num4;
268    }
269}
270 


0 0
原创粉丝点击