ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-11-24 10:04:18  阅读:202  来源: 互联网

标签:return double MyLatLng 线上 elevation 任意 public Math 坐标


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有