计算经纬度的中心点
2017-05-22 15:28阅读:
首先创建一个经纬度类
public class GeoCoordinate {
private double latitude;// 纬度
private double longitude;// 经度
public GeoCoordinate(double latitude2, double longitude2) {
this.latitude = latitude2;
this.longitude = longitude2;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
@Override
public String toString() {
return 'GeoCoordinate [latitude=' + latitude + ', longitude=' +
longitude + ']';
}
}
以下给出三种计算方法,根据实际情况调用
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import po.GeoCoordinate;
import org.junit.Test;
public class LongitudeAndLatitudeUtil {
private static final double EARTH_RADIUS = 6371393;// 地球半径
单位:米
// 将经纬度转为弧度
private static
double rad(double d) {
return d * Math.PI / 180.0;
}
public static double getDistance(GeoCoordinate gc1, GeoCoordinate
gc2) {
double radLat1 = rad(gc1.getLatitude());
double radLat2 = rad(gc2.getLatitude());
double a = radLat1 - radLat2;
double b = rad(gc1.getLongitude()) - rad(gc2.getLongitude());
double distance = (2 * Math.asin(Math.sqrt(
Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) *
Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))));
double distance1 = (distance * EARTH_RADIUS);
return distance1;
}
public static GeoCoordinate getCenterPoint(List geoCoordinateList)
{
int total = geoCoordinateList.size();
double X = 0, Y = 0, Z = 0;
for (GeoCoordinate gc : geoCoordinateList) {
double lat, lon, x, y, z;
lat = gc.getLatitude() * Math.PI / 180;
lon = gc.getLongitude() * Math.PI / 180;
x = Math.cos(lat) * Math.cos(lon);
y = Math.cos(lat) * Math.sin(lon);
z = Math.sin(lat);
X += x;
Y += y;
Z += z;
}
X = X / total;
Y = Y / total;
Z = Z / total;
double Lon = Math.atan2(Y, X);
double Hyp = Math.sqrt(X * X + Y * Y);
double Lat = Math.atan2(Z, Hyp);
return new GeoCoordinate(Lat * 180 / Math.PI, Lon * 180 /
Math.PI);
}
public static GeoCoordinate
GetCenterPointFromListOfCoordinates(List geoCoordinateList)
{
// 以下为简化方法(400km以内)
int total = geoCoordinateList.size();
double lat = 0.0, lon = 0.0;
for (GeoCoordinate gc : geoCoordinateList) {
lat += gc.getLatitude() * Math.PI / 180;
lon += gc.getLongitude() * Math.PI / 180;
}
lat /= total;
lon /= total;
return new GeoCoordinate(lat * 180 / Math.PI, lon * 180 /
Math.PI);
}
public static GeoCoordinate getCenter(List geoCoordinateList)
{
if (geoCoordinateList.size() == 0) {
return null;
}
List distanceGeoCoordinate = new ArrayList<>();
for (GeoCoordinate geoCoordinate : geoCoordinateList) {
geoCoordinate.setLongitude(geoCoordinate.getLongitude() * 85.39 *
1e3);
geoCoordinate.setLatitude(geoCoordinate.getLatitude() * 110 *
1e3);
distanceGeoCoordinate.add(geoCoordinate);
}
return getCenter1(distanceGeoCoordinate);
}
public static GeoCoordinate getCenter1(List distanceGeoCoordinate)
{
int th = 80;
double averLo = 0, averLa = 0;
List dists = new ArrayList<>();
for (GeoCoordinate geoCoordinate : distanceGeoCoordinate) {
averLa = averLa + geoCoordinate.getLatitude();
averLo = averLo + geoCoordinate.getLongitude();
}
averLa = averLa / distanceGeoCoordinate.size();
averLo = averLo / distanceGeoCoordinate.size();
double averdist = 0;
for (GeoCoordinate geoCoordinate : distanceGeoCoordinate) {
double distance = Math.sqrt(Math.pow(geoCoordinate.getLatitude() -
averLa, 2)
+ Math.pow(geoCoordinate.getLongitude() - averLo, 2));
averdist = averdist + distance;
dists.add(distance);
}
averdist = averdist / distanceGeoCoordinate.size();
double sum = 0;
for (double dist : dists) {
sum = sum + Math.pow(dist - averdist, 2);
}
sum = (sum / dists.size());
sum = Math.sqrt(sum) * 1.5; //1.5倍标准差是一个偏移,落在这个范围的概率86%
if (sum < th) {
return new GeoCoordinate(averLa / (110 * 1e3), averLo / (85.39 *
1e3));
} else {
int i = 0;
List geoCoordinates = new ArrayList<>();
for (double dist : dists) {
if (Math.abs(dist - averdist) < sum) {
GeoCoordinate geoCoordinate = new
GeoCoordinate(distanceGeoCoordinate.get(i).getLatitude(),
distanceGeoCoordinate.get(i).getLongitude());
geoCoordinates.add(geoCoordinate);
}
i++;
}
return getCenter1(geoCoordinates);
}
}
}