首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

java实例 - 使用数据库实现百度map纠偏

2014-01-26 
java实例 -使用数据库实现百度地图纠偏本文思路与代码实现完全参考了这篇文章:?gps纠偏数据库及gps纠偏算

java实例 - 使用数据库实现百度地图纠偏

本文思路与代码实现完全参考了这篇文章:?gps纠偏数据库及gps纠偏算法PHP

感谢文章作者yanue的无私分享与帮助.

以下代码中所使用到的数据库文件offset.dat请到yanue的网站进行下载.

?

正文代码如下:

package test.offset;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.URL;import java.net.URLConnection;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.springframework.util.Assert;import sun.misc.BASE64Decoder;/** * @author 200cc * */public class OffsetReader {static final double M_PI = 3.14159265358979323846264338327950288;static final double M_E = 2.71828182845904523536028747135266250;static final String DIR = "d:\\download\\offset.dat";/** * 读取数据库offset.dat文件 * @param count 读取数据计数 * @return * @throws Exception */public static OffsetData[] readOffset(int count) throws Exception{/** dat文件结构:该文件为0.01精度校正数据,并以lng和lat递增形式组合.* 其中以8个字节为一组:* lng : 2字节经度,如12151表示121.51* lat : 2字节纬度,如3130表示31.30* x_off : 2字节地图x轴偏移像素值* y_off : 2字节地图y轴偏移像素值**/OffsetData[] datas = new OffsetData[count];File f = new File(DIR);Assert.isTrue(f.exists() && f.isFile());FileInputStream fis = new FileInputStream(f);byte[] buf = new byte[8];@SuppressWarnings("unused")int len = 0;int cnt = 0;while(-1 != (len = fis.read(buf, 0, buf.length))){if (cnt >= count) break; int lngS = byte2short(buf, 0) ; // byte[] to shortint latS = byte2short(buf, 2) ; // byte[] to shortint x = byte2short(buf, 4) ; // byte[] to shortint y = byte2short(buf, 6) ; // byte[] to shortdatas[cnt] = new OffsetData(lngS, latS, x, y);cnt++;}return datas;}public static void main(String[] args) throws Exception {OffsetData[] datas = readOffset(10);for (OffsetData data : datas){System.out.println(data);geoLatLng(data);getBaiduGeo(data.getLat() * 1.0 / 100, data.getLng() * 1.0 / 100);                        System.out.println("----------------------");}}/** * 获取baidu api计算的经纬 * @param lat纬度 * @param lng经度 * @throws Exception */public static void getBaiduGeo(double lat, double lng) throws Exception{//baidu APIString urlAddr = "http://api.map.baidu.com/ag/coord/convert?x=" + lng + "&y=" + lat + "&from=0&to=2&mode=1";System.out.println("request: " + urlAddr);URL url = new URL(urlAddr);URLConnection connection = url.openConnection();connection.setDoOutput(true); //将连接设置为输出模式.即发起一个http请求//URLConnection通常作为输入来使用,如下载一个web页面.//但同时也能进行输出,将数据向web页面传送.OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "utf-8");out.flush();out.close();//发送成功后,获取得到服务器的响应InputStream is = connection.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));String line = "";StringBuilder sb = new StringBuilder();while(null != (line = br.readLine())){sb.append(line);}System.out.println("response: " + sb.toString());//[{"error":0,"x":"NzMuNTAzMzU1MDM0NzIy","y":"MzkuMzAwMTQxODcyODM="}]Pattern p = Pattern.compile(""x":"(.+)","y":"(.+)""); //正则Matcher m = p.matcher(sb.toString());String strLng = "", strLat = "";if(m.find()){BASE64Decoder decoder = new BASE64Decoder();strLng = new String(decoder.decodeBuffer(m.group(1)));strLat = new String(decoder.decodeBuffer(m.group(2)));}else{throw new RuntimeException("");}System.out.println("baidu Geo: " + strLat + ", " + strLng);Thread.sleep(1000); //暂停一会. baidu Api有发起次数限制.}/** * byte[] 转 short * @param b * @param index * @return */public static short byte2short(byte[] b, int index){ return (short) (((b[index + 1] << 8) | b[index + 0] & 0xff));}/** * byte[] 转 float * @param b * @param index * @return */public static float getFloat(byte[] b, int index) {      int l;      l = b[index + 0];      l &= 0xff;      l |= ((long) b[index + 1] << 8);      l &= 0xffff;      l |= ((long) b[index + 2] << 16);      l &= 0xffffff;      l |= ((long) b[index + 3] << 24);      return Float.intBitsToFloat(l);  }public static void geoLatLng(OffsetData data){geoLatLng(data.getLng() * 1.0 / 100, data.getLat() * 1.0 / 100, data.getOffsetPixelX(), data.getOffsetPixelY());}/** * 使用数据库计算经纬度坐标 * @param lng 实际(gps)经度 * @param lat实际(gps)纬度 * @param offsetX地图x轴偏移像素值 * @param offsetY地图y轴偏移像素值 */public static void geoLatLng(double lng, double lat, int offsetX, int offsetY){double lngPixel = lngToPixel(lng, 18) + offsetX;double latPixel = latToPixel(lat, 18) + offsetY;double mixLat = pixelToLat(latPixel, 18);double mixLng = pixelToLng(lngPixel, 18);System.out.println("calculate geo: " + mixLat + ", " + mixLng);}public static double lngToPixel(double lng, int zoom){double res = (lng  + 180) * (256 << zoom) / 360;//System.out.println("lngToPixel: lng=" + lng + " --> res=" + res );return res;}public static double latToPixel(double lat , int zoom){double siny = Math.sin(lat * M_PI / 180);double y = Math.log((1 + siny) / (1 - siny));double res = (128 << zoom) * (1 - y / (2 * M_PI));//System.out.println("latToPixel: lat=" + lat + " --> res=" + res );return res;}public static double pixelToLng(double pixelX, int zoom){double res = pixelX * 360 / (256 << zoom) - 180;//System.out.println("pixelToLng: pixelX=" + pixelX + " --> res=" + res );return res;}public static double pixelToLat(double pixelY, int zoom){double y = 2 * M_PI * (1 - pixelY /(128 << zoom));double z = Math.pow(M_E , y);double siny = (z - 1) / (z + 1);double res = Math.asin(siny) * 180 / M_PI;//System.out.println("pixelToLat: pixelY=" + pixelY + " --> res=" + res );return res;}public static class OffsetData{int lng;int lat;int offsetPixelX;int offsetPixelY;public OffsetData(int lng, int lat, int x, int y){this.lng = lng;this.lat = lat;this.offsetPixelX = x;this.offsetPixelY = y;}public String toString(){return this.lng + ", " + this.lat + ", " + this.offsetPixelX + ", " + this.offsetPixelY;}public int getLng() {return lng;}public void setLng(int lng) {this.lng = lng;}public int getLat() {return lat;}public void setLat(int lat) {this.lat = lat;}public int getOffsetPixelX() {return offsetPixelX;}public void setOffsetPixelX(int offsetPixelX) {this.offsetPixelX = offsetPixelX;}public int getOffsetPixelY() {return offsetPixelY;}public void setOffsetPixelY(int offsetPixelY) {this.offsetPixelY = offsetPixelY;}}}

?

运行后结果:

7350, 3930, 624, -35calculate geo: 39.30014529193229, 73.50334739685061request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.3&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU1MDM0NzIy","y":"MzkuMzAwMTQxODcyODM="}]baidu Geo: 39.30014187283, 73.503355034722----------------------7350, 3931, 624, -36calculate geo: 39.31014942177512, 73.50334739685061request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.31&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU1MzA1OTk=","y":"MzkuMzEwMTQ2NzU1NjQy"}]baidu Geo: 39.310146755642, 73.50335530599----------------------7350, 3932, 624, -37calculate geo: 39.32015355042689, 73.50334739685061request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.32&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU1NTc3MjU3","y":"MzkuMzIwMTUxMzY3MTg3"}]baidu Geo: 39.320151367187, 73.503355577257----------------------7350, 3933, 625, -38calculate geo: 39.33015767788718, 73.50335276126864request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.33&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU2MTE5Nzky","y":"MzkuMzMwMTU1NzA3NDY1"}]baidu Geo: 39.330155707465, 73.503356119792----------------------7350, 3934, 625, -39calculate geo: 39.34016180415566, 73.50335276126864request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.34&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU2MzkxMDU5","y":"MzkuMzQwMTYwMzE5MDE="}]baidu Geo: 39.34016031901, 73.503356391059----------------------7350, 3935, 625, -40calculate geo: 39.350165929231935, 73.50335276126864request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.35&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU2NjYyMzI2","y":"MzkuMzUwMTY0NjU5Mjg4"}]baidu Geo: 39.350164659288, 73.503356662326----------------------7350, 3936, 625, -41calculate geo: 39.36017005311557, 73.50335276126864request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.36&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU2OTMzNTk0","y":"MzkuMzYwMTY4OTk5NTY2"}]baidu Geo: 39.360168999566, 73.503356933594----------------------7350, 3937, 625, -42calculate geo: 39.37017417580627, 73.50335276126864request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.37&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU3NDc2MTI4","y":"MzkuMzcwMTczMDY4NTc2"}]baidu Geo: 39.370173068576, 73.503357476128----------------------7350, 3938, 625, -43calculate geo: 39.380178297303594, 73.50335276126864request: http://api.map.baidu.com/ag/coord/convert?x=73.5&y=39.38&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTAzMzU3NzQ3Mzk2","y":"MzkuMzgwMTc3MTM3NTg3"}]baidu Geo: 39.380177137587, 73.503357747396----------------------7351, 3930, 616, -28calculate geo: 39.30011623356995, 73.51330448150634request: http://api.map.baidu.com/ag/coord/convert?x=73.51&y=39.3&from=0&to=2&mode=1response: [{"error":0,"x":"NzMuNTEzMzEyMTc0NDc5","y":"MzkuMzAwMTEyMDMzNDI="}]baidu Geo: 39.30011203342, 73.513312174479----------------------

?

总结:

从运行结果可以看到,使用数据库计算后的结果,与baidu返回的数据间的差值大约在0.0001左右.误差值还是挺大的.- -b.

?

本人能力有限,代码中肯定还存在错误,恳请诸位指正.

?

此外还衍生出一个问题:?我在网上查到

Q:百度坐标为何有偏移?A:国际经纬度坐标标准为WGS-84,国内必须至少使用国测局制定的GCJ-02,对地理位置进行首次加密。百度坐标在此基础上,进行了BD-09二次加密措施,更加保护了个人隐私。...

?使用这个offset.dat数据文件,计算得到的值居然能粗略拟合百度的二次火星坐标,我自己都觉得这是不是有些不可思议了?

热点排行