处理GoogleMap坐标和GPS坐标和BaiduMap坐标

    首先,这个问题烦恼了我很久了,因为手上是一个离线地图的项目,需要做切片地图等等,而我们手里能拿到的数据只有GPS的数据,然后放在GoogleMap(我们的离线地图使用的是Google的切片算法)上进行测试,就发现偏差在600米以上,这就是一个很头痛的问题,原本以为这是GPS本身的误差,就没管了.

    后来,我才知道,这是一个叫做西安80的坐标系在搞鬼,因为国家安全…..

    所以,GPS使用国际标准,GoogleMap使用中国i标准,所以就…..了.

    网上找了半天,终于发现百度提供了换算的方法,而且精度不错.用这个可以实现自己的偏移数据库,然后暴搜找结果.

    下面是具体的代码,另外最后附上苏州地区的偏移库,点击这.

    因为有200万组数据,所以我就开线程做了,如果数据多,会比较慢.最好使用线程池做.

    具体的代码实现,请看这.

    还是简单的扯扯吧,主要的代码在下面,祝各位开心

    

package iot.mike.gpscheck;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.util.Base64;

/**
 * GPS偏移库抓取,依赖百度API
 * 结果保存在文件中,格式为:
 * "GPS经度 GPS纬度:结果经度 结果纬度\n"
 * 为加快速度,采用了线程池
 * 
 * @author mikecoder
 * @date 2013-8-15
 */
public class GPSCheck {
	private static File GPSFile = new File("GPS.txt");//导入的文件
	
	private static FileWriter writer;
	private static final int GPS2GoogleMap = 2;
	private static final int GPS2BaiduMap = 4;
	private static final int GoogleMap2BaiduMap = 3;
	
	//----------------------------------------------------------
	//这边的数值按照需要进行修改
	private static double topLatitude = 31.3306;
	private static double bottomLatitude = 31.2408;
	private static double leftLongtitude = 120.5297;
	private static double rightLongtitude = 120.7549;
	private static int type = GPS2GoogleMap;
	private static double accuracy = 0.0001;
	
	//------------------------------------------------------------
	public static class Location{
		public String x;
		public String y;
		public int error;
	}
	
	private static class GPSRunnable implements Runnable{
		private Location GPSLocation = new Location();
		
		public GPSRunnable(Location location){
			this.GPSLocation = location;
		}
		
		public void run() {
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpGet get = new HttpGet(
					"http://api.map.baidu.com/ag/coord/convert?from=0"
					+ "&to=" + type
					+ "&x=" + GPSLocation.x
					+ "&y=" + GPSLocation.y);
			try {
				HttpResponse response = httpClient.execute(get);
				HttpEntity entity = response.getEntity();
				InputStream reader = entity.getContent();
				byte[] content = new byte[1024];
				int size = 0;
				String data = new String();
				while ((size = reader.read(content)) != -1) {
					data = data + new String(content, 0, size);
				}
				System.out.println(data);
				Location aLocation = 
						(Location)JSON.parseObject(data, Location.class);
				if (aLocation.error == 0) {//错误数据不写入
					byte[] x = Base64.decodeFast(aLocation.x);
					String xString = new String(x);
					byte[] y = Base64.decodeFast(aLocation.y);
					String yString = new String(y);
					
					synchronized (writer) {
						writer.write(GPSLocation.x.substring(0, 8) + 
								" " + GPSLocation.y.substring(0, 7) + 
								":" + xString.substring(0, 8) + 
								" " + yString.substring(0, 7) + "\n");
						System.out.println(GPSLocation.x.substring(0, 8) +
								" " + 
								GPSLocation.y.substring(0, 7) + 
								":" + xString.substring(0, 8) + 
								" " + yString.substring(0, 7) + "\n");
						writer.flush();
					}
				}
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) 
                            throws IOException, InterruptedException {
		if (!GPSFile.exists()) {
			try {
				GPSFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		writer = new FileWriter(GPSFile);
		ThreadPoolExecutor threadpool = new ThreadPoolExecutor(
				5000, //核心线程数
				15000, //最大线程数
				5, TimeUnit.MINUTES,	//线程空闲等待 
				new ArrayBlockingQueue<Runnable>(300)	//命令队列
				);
		//根据自己电脑性能酌情修改
		int num = ((int)((topLatitude - bottomLatitude)/accuracy) 
				*(int)((leftLongtitude - rightLongtitude)/accuracy));
		System.out.println("所需要的数据总数:" + Math.abs(num));
		
		for (double i = topLatitude; 
				i > bottomLatitude; 
				i = i - accuracy) {
			for (double j = leftLongtitude; 
					j < rightLongtitude; 
					j = j + accuracy) {
				Location aLocation = new Location();
				aLocation.x = String.valueOf(j);
				aLocation.y = String.valueOf(i);
				
				GPSRunnable gRunnable = new GPSRunnable(aLocation);
				threadpool.execute(gRunnable);
				Thread.sleep(10);
				//如果不暂停,各位可以试试,不知道你们的电脑能不能撑的住..
			}
		}
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *