本文思路与代码实现完全参考了这篇文章:?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 short int latS = byte2short(buf, 2) ; // byte[] to short int x = byte2short(buf, 4) ; // byte[] to short int y = byte2short(buf, 6) ; // byte[] to short datas[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 API String 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)); }