c# - Calculate future latitude longitude with initial coordinates, heading and distance -
i have been reading through stackoverflow , site (http://www.movable-type.co.uk/scripts/latlong.html) how this, cant code give correct answer. giving coordinate isnt in correct direction. have been working on day , seem have hit wall. function:
public static void destination() { double heading = 335.9; double startlatitude = 41.8369; double startlongitude = 87.6847; //convert radians startlatitude = startlatitude * math.pi / 180; startlongitude = startlongitude * math.pi / 180; heading = heading * math.pi / 180; int distancekilometers = 100; double angulardistance = distancekilometers / 6371e3; double endlat = math.asin((math.sin(startlatitude) * math.cos(angulardistance)) + (math.cos(startlatitude) * math.sin(angulardistance) * math.cos(heading))); double endlong = startlongitude + (math.atan2((math.sin(heading) * math.sin(angulardistance) * math.cos(startlatitude)), math.cos((angulardistance) - (math.sin(startlatitude) * math.sin(endlat))))); endlong = (endlong + 3 * math.pi) % (2 * math.pi) - math.pi; console.writeline("endlatitude: " + (endlat * 180 / math.pi) + " endlongitude: " + (endlong * 180 / math.pi)); }
i use below function. float provide 3 meters precision. if need more, use double.
internal class sxmath { internal const float pi = (float)math.pi; internal const float x2pi = pi * 2; internal const float pidiv2 = pi/2; internal const float radpersec = (float)(pi / 648000f); internal const float secperrad = (float)(648000f / pi); internal const float radperdeg = pi / 180; internal const float radpermin = pi / 10800; internal const float degperrad = 180 / pi; internal const float minparrad = (float)(10800.0/pi); internal const float radpermeter = radpermin * (1f/1852f) /* meter_to_nms */ ; internal static float realmod(float val,float modval) { // example : realmod(3,2*pi)=3 , realmod(2*pi+3,2*pi)=3 , realmod(-3,2*pi)=2*pi-3 float result = (float)math.ieeeremainder(val,modval); if (result<0) result = result + modval; return result; } } // sxmath internal struct sxgeopt { internal float lat ; // in radians, n positive internal float lon ; // in radians, w positive } // sxgeopt internal static sxgeopt geo_coorpointinazim(sxgeopt p1,float az,float raddist) // procedure provides coordinates of point p2 located // - @ distance raddist of point p1 // - in direction of azimuth az // input p1 <sxgeopt> coordinates of reference point // raddist <float> distance in radian between p1 , p2 // az <float> azimut of p2 p1, // (az=0, if p1 , p2 on same longitude , p2 north of p1) // (az=90, if p1 on equator , p2 on equtor @ east of p1) // output p2 <sxgeopt> coordinates of resulting point { sxgeopt result; if (p1.lat>sxmath.pidiv2-sxmath.radpermin) { if (az<=sxmath.pi) result.lon=az; else result.lon=az-sxmath.pi; result.lat=sxmath.pidiv2-raddist; } else if (p1.lat<-sxmath.pidiv2+sxmath.radpermin) { if (az<=sxmath.pi) result.lon=-az; else result.lon=-az+sxmath.pi; result.lat=-sxmath.pidiv2+raddist; } else { result.lat = (float)math.asin((math.sin(p1.lat)*math.cos(raddist)) + (math.cos(p1.lat)*math.sin(raddist)*math.cos(az))); float dlon = (float)math.atan2( math.sin(az)*math.sin(raddist)*math.cos(p1.lat), math.cos(raddist)-math.sin(p1.lat)*math.sin(result.lat)); result.lon = sxmath.realmod(p1.lon-dlon+sxmath.pi,sxmath.x2pi)-sxmath.pi; } return result; }
as extracted code different classes, hope nothing missing.
to input parameter distinrad kilometers:
float raddist = distancekilometers * 1000f * sxmath.radpermeter ;
Comments
Post a Comment