从网上看到的算法,不是我自己想的,实现了以后又有更好的方式来解决问题了。在这儿把代码保留一下。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Date;
import component.map.model.LatLng;
public class GPSOffset {
private float _offsets[][];
private int _expLong = 10; //经纬度放大系数,代表了纠偏精度。0.1精度时为10
private int _minX = 73;
private int _maxX = 135;
private int _minY = 18;
private int _maxY = 54;
public GPSOffset(String file, int minX, int maxX, int minY, int maxY, int exp){
int jingdu = 1000000;
_minX = minX;
_maxX = maxX;
_minY = minY;
_maxY = maxY;
_expLong = exp;
File f = new File(file);
int size = (_maxX - _minX) * (_maxY - _minY) * _expLong * _expLong;
_offsets = new float[size][2];
BufferedReader bf;
try{
bf = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
String str;
int i = 0;
while(null != (str = bf.readLine())){
String s[]=str.split(",");
_offsets[i][0] = (float) (Float.parseFloat(s[0]) / jingdu);
_offsets[i][1] = (float) (Float.parseFloat(s[1]) / jingdu);
i++;
}
bf.close();
}
catch(Exception e){
e.printStackTrace();
}
}
public LatLng getOffset(LatLng position){
double lat = position.getLat();
double lng = position.getLng();
if(lng < _minX || lng >= _maxX || lat < _minY || lat >= _maxY){
return new LatLng(0.0, 0.0);
}
lat *= _expLong;
lng *= _expLong;
//计算该真实坐标点四周的纠偏点坐标(上取整,下取整)
int x1 = (int)Math.floor(lng), x2 = (int)Math.ceil(lng);
int y1 = (int)Math.floor(lat), y2 = (int)Math.ceil(lat);
//根据四个周边点的取整(已放大),读取纠偏数据
LatLng mo0 = getRegOffset(x1, y1);
LatLng mo1 = getRegOffset(x1, y2);
LatLng mo2 = getRegOffset(x2, y1);
LatLng mo3 = getRegOffset(x2, y2);
if( x1 == x2 && y1 == y2 ){
return mo0;
}
if( x1 == x2 ){
double offsetX = mo0.getLng() * (y2 - lat) + mo1.getLng() * (lat - y1);
double offsetY = mo0.getLat() * (y2 - lat) + mo1.getLat() * (lat - y1);
return new LatLng(offsetY, offsetX);
}
if( y1 == y2 ){
double offsetX = mo0.getLng() * (x2 - lng) + mo1.getLng() * (lng - x1);
double offsetY = mo0.getLat() * (x2 - lng) + mo1.getLat() * (lng - x1);
return new LatLng(offsetY, offsetX);
}
//计算纠偏点影响系数
double coef0 = (lng - x1) * (lat - y1);
double coef1 = (lng - x1) * (y2 - lat);
double coef2 = (x2 - lng) * (lat - y1);
double coef3 = (x2 - lng) * (y2 - lat);
LatLng offset = new LatLng();
offset.setLat(mo0.getLat() * coef0 + mo1.getLat() * coef1 + mo2.getLat() * coef2 + mo3.getLat() * coef3);
offset.setLng(mo0.getLng() * coef0 + mo1.getLng() * coef1 + mo2.getLng() * coef2 + mo3.getLng() * coef3);
return offset;
}
// 取正常精度的偏移量, lng和lat是扩大_expLong后的数值
public LatLng getRegOffset(int lng, int lat) {
int index = (lat / _expLong - _minY) * ((_maxX - _minX) * _expLong * _expLong)
+ (lng / _expLong - _minX) * (_expLong * _expLong)
+ (lat - _minY * _expLong ) * _expLong
+ (lng - _minX * _expLong);
return new LatLng(_offsets[index][0], _offsets[index][1]);
}
public static void main(String[] args){
String gfile01 = "D:/workspace/gmap_api/converter/ggOffset/data_0.1/offset_36_117.csv";
String gfile001 = "D:/workspace/gmap_api/converter/ggOffset/data_0.01/offset_36_117.csv";
String bfile001 = "D:/workspace/gmap_api/converter/bdOffset/data_0.01/offset_36_117.csv";
GPSOffset go01 = new GPSOffset(gfile01, 117, 118, 36, 37, 10);
GPSOffset go001 = new GPSOffset(gfile001, 117, 118, 36, 37, 100);
GPSOffset bo001 = new GPSOffset(bfile001, 117, 118, 36, 37, 100);
LatLng p1 = new LatLng(36.205, 117.315);
LatLng p2 = new LatLng(36.195, 117.295);
LatLng p3 = new LatLng(36.255, 117.355);
LatLng p4 = new LatLng(36.4, 117.56);
LatLng ll, ll1;
ll = go01.getOffset(p1);
ll1 = go001.getOffset(p1);
System.out.println(ll.toJSONString());
System.out.println(ll1.toJSONString());
ll = go01.getOffset(p2);
ll1 = go001.getOffset(p2);
System.out.println(ll.toJSONString());
System.out.println(ll1.toJSONString());
ll = go01.getOffset(p3);
ll1 = go001.getOffset(p3);
System.out.println(ll.toJSONString());
System.out.println(ll1.toJSONString());
ll = go01.getOffset(p4);
ll1 = go001.getOffset(p4);
System.out.println(ll.toJSONString());
System.out.println(ll1.toJSONString());
}
}