首先,这个问题烦恼了我很久了,因为手上是一个离线地图的项目,需要做切片地图等等,而我们手里能拿到的数据只有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);
//如果不暂停,各位可以试试,不知道你们的电脑能不能撑的住..
}
}
}
}