其他分享
首页 > 其他分享> > 已知地球上的2点坐标,A和B,求A,B线上 任意点位置。

已知地球上的2点坐标,A和B,求A,B线上 任意点位置。

作者:互联网

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();
   }
}

  

标签:return,double,MyLatLng,线上,elevation,任意,public,Math,坐标
来源: https://www.cnblogs.com/fengyingwang/p/14028652.html