已知地球上的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