日期:2014-05-16  浏览次数:20629 次

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 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));
	}