public static GeoPoint caculateWGS84GeoPoint(GeoPoint aPoint, GeoPoint bPoint, double distance_ax_in_meter) {
if (geoCalc == null) {
geoCalc = new GeodeticCalculator();
}
double startBearing = AngleUtil.getAngel(aPoint, bPoint);
GlobalCoordinates start = new GlobalPosition(aPoint.getLatitude(), aPoint.getLongitude(), aPoint.getAltitude());
GlobalCoordinates x = geoCalc.calculateEndingGlobalCoordinates(Ellipsoid.WGS84, start, startBearing, distance_ax_in_meter);
GeoPoint xPoint = new GeoPoint(x.getLongitude(), x.getLatitude());
return xPoint;
}
/**
* https://blog.csdn.net/u010980446/article/details/45268299
*/
public class AngleUtil {
public static void main(String[] args) {
MyLatLng A=new MyLatLng(113.249648,23.401553);
MyLatLng B=new MyLatLng(113.246033,23.403362);
System.out.println(getAngle(A,B));
}
/**
* 已知道A 点,B点的经纬度,84坐标系, X点在A和B之间.[Ax<AB AB取穿过地球球心最短弧长这条] 求X坐标位置
* @param A
* @param B
* @param distance_in_km_ax
* @return
*/
public static MyLatLng caculateRawGeoPoint(MyLatLng A, MyLatLng B, double distance_in_km_ax){
MyLatLng newMyLatLng=null;
double angle = getAngle(A,B);
//这个有问题.
double distance_A_X_in_KM = GeoPointTransform.distance(new GeoPoint(A.m_Longitude,A.m_Latitude),new GeoPoint(B.m_Longitude,B.m_Latitude))/1000.0d;
if(distance_A_X_in_KM<=distance_in_km_ax) {
newMyLatLng = getMyLatLng(A, distance_in_km_ax, angle);
}
else{
newMyLatLng = getMyLatLng(A, Math.max(distance_in_km_ax,distance_A_X_in_KM), angle);
System.out.println("请注意:X点不在A点和B点之间,您是不是要计算AB线上,在B之后的点"+newMyLatLng);
newMyLatLng = null;
}
return newMyLatLng;
}
/**
* 求B点经纬度
* @param A 已知点的经纬度,
* @param distanceInKM AB两地的距离 单位km
* @param angle AB连线与正北方向的夹角(0~360)
* @return B点的经纬度
*/
public static MyLatLng getMyLatLng(MyLatLng A,double distanceInKM,double angle){
double dx = distanceInKM*1000*Math.sin(Math.toRadians(angle));
double dy= distanceInKM*1000*Math.cos(Math.toRadians(angle));
double bjd=(dx/A.Ed+A.m_RadLo)*180./Math.PI;
double bwd=(dy/A.Ec+A.m_RadLa)*180./Math.PI;
return new MyLatLng(bjd, bwd);
}
/**
* 求B点经纬度
* @param wgs84GeoPointA 已知点的经纬度,
* @param distanceInMeter AB两地的距离 单位km
* @param angle AB连线与正北方向的夹角(0~360)
* @return B点的经纬度
*/
public static GeoPoint caculateRawGeoPoint(GeoPoint wgs84GeoPointA,double distanceInMeter,double angle){
double dx = distanceInMeter*Math.sin(Math.toRadians(angle));
double dy= distanceInMeter*Math.cos(Math.toRadians(angle));
MyLatLng A = new MyLatLng(wgs84GeoPointA.getLongitude(),wgs84GeoPointA.getLatitude());
double bjd=(dx/A.Ed+A.m_RadLo)*180./Math.PI;
double bwd=(dy/A.Ec+A.m_RadLa)*180./Math.PI;
GeoPoint newGeoPoint = new GeoPoint(bjd,bwd,0.0);
return newGeoPoint;
}
/**
* 获取AB连线与正北方向的角度
* @param A A点的经纬度
* @param B B点的经纬度
* @return AB连线与正北方向的角度(0~360)
*/
public static double getAngle(MyLatLng A,MyLatLng B){
double dx=(B.m_RadLo-A.m_RadLo)*A.Ed;
double dy=(B.m_RadLa-A.m_RadLa)*A.Ec;
double angle=0.0;
angle=Math.atan(Math.abs(dx/dy))*180./Math.PI;
double dLo=B.m_Longitude-A.m_Longitude;
double dLa=B.m_Latitude-A.m_Latitude;
if(dLo>0&&dLa<=0){
angle=(90.-angle)+90;
}
else if(dLo<=0&&dLa<0){
angle=angle+180.;
}else if(dLo<0&&dLa>=0){
angle= (90.-angle)+270;
}
return angle;
}
public static double getAngel(GeoPoint wgs84GeoPointA, GeoPoint wgs84GeoPointB){
MyLatLng A = new MyLatLng(wgs84GeoPointA.getLongitude(),wgs84GeoPointA.getLatitude());
MyLatLng B = new MyLatLng(wgs84GeoPointB.getLongitude(),wgs84GeoPointB.getLatitude());
double angel=0.0;
angel=getAngle(A,B);
return angel;
}
static class MyLatLng {
final static double Rc=6378137;
final static double Rj=6356752;//6356725
double m_LoDeg,m_LoMin,m_LoSec;
double m_LaDeg,m_LaMin,m_LaSec;
double m_Longitude,m_Latitude;
double m_RadLo,m_RadLa;
double Ec;
double Ed;
public MyLatLng(double longitude,double latitude){
m_LoDeg=(int)longitude;
m_LoMin=(int)((longitude-m_LoDeg)*60);
m_LoSec=(longitude-m_LoDeg-m_LoMin/60.)*3600;
m_LaDeg=(int)latitude;
m_LaMin=(int)((latitude-m_LaDeg)*60);
m_LaSec=(latitude-m_LaDeg-m_LaMin/60.)*3600;
m_Longitude=longitude;
m_Latitude=latitude;
m_RadLo=longitude*Math.PI/180.;
m_RadLa=latitude*Math.PI/180.;
Ec=Rj+(Rc-Rj)*(90.-m_Latitude)/90.;
Ed=Ec*Math.cos(m_RadLa);
}
}
/**
* 已知WGS84坐标系 A 点,B点, X 在AB 弧线上, 且是最短的这条, AX距离已知,求X点坐标.
* @param aPoint
* @param bPoint
* @param distance_ax_in_meter
* @return
*/
public static GeoPoint caculateRawGeoPoint(GeoPoint aPoint, GeoPoint bPoint, double distance_ax_in_meter){
MyLatLng a= new MyLatLng(aPoint.getLongitude(),aPoint.getLatitude());
MyLatLng b = new MyLatLng(bPoint.getLongitude(),bPoint.getLatitude());
double angle=getAngle(a,b); //getAngle(a,x)==getAngle(a,b)
MyLatLng x= getMyLatLng(a,distance_ax_in_meter/1000.0,angle);
GeoPoint xPoint = new GeoPoint(x.m_Longitude,x.m_Latitude);
return xPoint;
}
/**
* https://stackoverflow.com/questions/837872/calculate-distance-in-meters-when-you-know-longitude-and-latitude-in-java
* @return 这个精准度比较差
*/
public static double rawDistance(GeoPoint wgs84GeoPointA, GeoPoint wgs84GeoPointB) {
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(wgs84GeoPointB.getLatitude()-wgs84GeoPointA.getLatitude());
double dLng = Math.toRadians(wgs84GeoPointB.getLongitude()-wgs84GeoPointA.getLongitude());
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(wgs84GeoPointA.getLatitude())) * Math.cos(Math.toRadians(wgs84GeoPointB.getLatitude())) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double distanceAB = earthRadius * c;
return distanceAB;
}
}
/*
* Geodesy by Mike Gavaghan
*
* http://www.gavaghan.org/blog/free-source-code/geodesy-library-vincentys-formula/
*
* Copyright 2007 Mike Gavaghan - mike@gavaghan.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* BitCoin tips graciously accepted at 1FB63FYQMy7hpC2ANVhZ5mSgAZEtY1aVLf
*/
package org.gavaghan.geodesy;
/**
* <p>
* Encapsulates a three dimensional location on a globe (GlobalCoordinates
* combined with an elevation in meters above a reference ellipsoid).
* </p>
* <p>
* See documentation for GlobalCoordinates for details on how latitude and
* longitude measurements are canonicalized.
* </p>
*
* @author <a href="mailto:mike@gavaghan.org">Mike Gavaghan</a>
*/
public class GlobalPosition extends GlobalCoordinates
{
/** Elevation, in meters, above the surface of the ellipsoid. */
private double mElevation;
/**
* Creates a new instance of GlobalPosition.
*
* @param latitude
* latitude in degrees
* @param longitude
* longitude in degrees
* @param elevation
* elevation, in meters, above the reference ellipsoid
*/
public GlobalPosition(double latitude, double longitude, double elevation)
{
super(latitude, longitude);
mElevation = elevation;
}
/**
* Creates a new instance of GlobalPosition.
*
* @param coords
* coordinates of the position
* @param elevation
* elevation, in meters, above the reference ellipsoid
*/
public GlobalPosition(GlobalCoordinates coords, double elevation)
{
this(coords.getLatitude(), coords.getLongitude(), elevation);
}
/**
* Get elevation.
*
* @return elevation about the ellipsoid in meters.
*/
public double getElevation()
{
return mElevation;
}
/**
* Set the elevation.
*
* @param elevation
* elevation about the ellipsoid in meters.
*/
public void setElevation(double elevation)
{
mElevation = elevation;
}
/**
* Compare this position to another. Western longitudes are less than
* eastern longitudes. If longitudes are equal, then southern latitudes are
* less than northern latitudes. If coordinates are equal, lower elevations
* are less than higher elevations
*
* @param other
* instance to compare to
* @return -1, 0, or +1 as per Comparable contract
*/
public int compareTo(GlobalPosition other)
{
int retval = super.compareTo(other);
if (retval == 0)
{
if (mElevation < other.mElevation) retval = -1;
else if (mElevation > other.mElevation) retval = +1;
}
return retval;
}
/**
* Get a hash code for this position.
*
* @return hash code
*/
@Override
public int hashCode()
{
int hash = super.hashCode();
if (mElevation != 0) hash *= (int) mElevation;
return hash;
}
/**
* Compare this position to another object for equality.
*
* @param obj object to compare to
* @return 'true' if objects are equal
*/
@Override
public boolean equals(Object obj)
{
if (!(obj instanceof GlobalPosition)) return false;
GlobalPosition other = (GlobalPosition) obj;
return (mElevation == other.mElevation) && (super.equals(other));
}
/**
* Get position as a string.
*/
@Override
public String toString()
{
StringBuffer buffer = new StringBuffer();
buffer.append(super.toString());
buffer.append("elevation=");
buffer.append(Double.toString(mElevation));
buffer.append("m");
return buffer.toString();
}
}