Esempio n. 1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <returns></returns>
        public static double AngularDistance(IKmlPoint point1, IKmlPoint point2)
        {
            double phi1 = point1.getLatitude().DegreesToRadians();
            double phi2 = point2.getLatitude().DegreesToRadians();
            double d_phi = (point2.getLatitude() - point1.getLatitude()).DegreesToRadians();
            double d_lmd = (point2.getLongitude() - point1.getLongitude()).DegreesToRadians();
            double A = Math.Pow(Math.Sin(d_phi / 2), 2) +
                Math.Cos(phi1) * Math.Cos(phi2) *
                Math.Pow(Math.Sin(d_lmd / 2), 2);

            return 2 * Math.Atan2(Math.Sqrt(A), Math.Sqrt(1 - A));
        }
Esempio n. 2
0
 /// <summary>
 /// Draws the line string.
 /// </summary>
 /// <param name="ge">The ge.</param>
 /// <param name="p1">The p1.</param>
 /// <param name="p2">The p2.</param>
 /// <returns></returns>
 public static IKmlPlacemark DrawLineString(IGEPlugin ge, IKmlPoint p1, IKmlPoint p2)
 {
     IKmlPlacemark lineStringPlacemark = ge.createPlacemark(String.Empty);
     IKmlLineString lineString = ge.createLineString(String.Empty);
     lineStringPlacemark.setGeometry(lineString);
     lineString.setTessellate(1);
     lineString.getCoordinates().pushLatLngAlt(p1.getLatitude(), p1.getLongitude(), 0);
     lineString.getCoordinates().pushLatLngAlt(p2.getLatitude(), p2.getLongitude(), 0);
     return lineStringPlacemark;
 }
Esempio n. 3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="origin">The first point</param>
        /// <param name="heading"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static IKmlPoint Destination(IKmlPoint origin, double heading, double distance)
        {
            double phi1 = origin.getLatitude().DegreesToRadians();
            double lmd1 = origin.getLongitude().DegreesToRadians();

            double sin_phi1 = Math.Sin(phi1);
            double angularDistance = distance / EARTH_RADIUS;
            double heading_rad = heading.DegreesToRadians();
            double sin_angularDistance = Math.Sin(angularDistance);
            double cos_angularDistance = Math.Cos(angularDistance);

            double phi2 =
                Math.Asin(sin_phi1 * cos_angularDistance + Math.Cos(phi1) *
                sin_angularDistance * Math.Cos(heading_rad));

            IKmlPoint result = origin;
            result.set(0, 0, 0, 0, 0, 0);
            result.setLatLng(phi2.RadiansToDegrees(),
                Math.Atan2(Math.Sin(heading_rad) * sin_angularDistance * Math.Cos(phi2),
                cos_angularDistance - sin_phi1 * Math.Sin(phi2)).RadiansToDegrees() + origin.getLongitude());

            return result;
        }
Esempio n. 4
0
        /// <summary>
        /// Calculates an intermediate point on the geodesic between the two given points 
        /// See: http://williams.best.vwh.net/avform.htm#Intermediate
        /// </summary>
        /// <param name="origin">The first point</param>
        /// <param name="destination">The second point</param>
        /// <param name="fraction">Intermediate location as a decimal fraction (T value)</param>
        /// <returns></returns>
        public static IKmlPoint IntermediatePoint(IKmlPoint origin, IKmlPoint destination, double fraction)
        {
            if (fraction > 1 || fraction < 0)
            {
                throw new ArgumentOutOfRangeException("fraction must be between 0 and 1");
            }

            // TODO: check for antipodality and fail w/ exception in that case
            double phi1 = origin.getLatitude().DegreesToRadians();
            double phi2 = destination.getLatitude().DegreesToRadians();
            double lmd1 = origin.getLongitude().DegreesToRadians();
            double lmd2 = destination.getLongitude().DegreesToRadians();

            double cos_phi1 = Math.Cos(phi1);
            double cos_phi2 = Math.Cos(phi2);
            double angularDistance = AngularDistance(origin, destination);
            double sin_angularDistance = Math.Sin(angularDistance);

            double A = Math.Sin((1 - fraction) * angularDistance) / sin_angularDistance;
            double B = Math.Sin(fraction * angularDistance) / sin_angularDistance;
            double x = A * cos_phi1 * Math.Cos(lmd1) + B * cos_phi2 * Math.Cos(lmd2);
            double y = A * cos_phi1 * Math.Sin(lmd1) + B * cos_phi2 * Math.Sin(lmd2);
            double z = A * Math.Sin(phi1) + B * Math.Sin(phi2);

            IKmlPoint result = origin;
            result.set(0, 0, 0, 0, 0, 0);
            result.setLatLng(Math.Atan2(z, Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2))).RadiansToDegrees(),
                Math.Atan2(y, x).RadiansToDegrees());

            return result;
        }
Esempio n. 5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="destination"></param>
        /// <returns></returns>
        public static double Heading(IKmlPoint origin, IKmlPoint destination)
        {
            double phi1 = origin.getLatitude().DegreesToRadians();
            double phi2 = destination.getLatitude().DegreesToRadians();
            double cos_phi2 = Math.Cos(phi2);
            double d_lmd = (destination.getLongitude() - origin.getLongitude()).DegreesToRadians();

            return NormaliseAngle(
                Math.Atan2(Math.Sin(d_lmd) * cos_phi2,
                Math.Cos(phi1) * Math.Sin(phi2) - Math.Sin(phi1) *
                cos_phi2 * Math.Cos(d_lmd))).RadiansToDegrees();
        }
Esempio n. 6
0
        /// <summary>
        /// This function is based on the geodesy-library code by Mike Gavaghan 
        /// See http://www.gavaghan.org/blog/2007/08/06/c-gps-receivers-and-geocaching-vincentys-formula/
        /// </summary>
        /// <param name="origin">The first point</param>
        /// <param name="destination">The second point</param>
        /// <returns>The distance between the given points in metres</returns>
        public static double DistanceVincenty(IKmlPoint origin, IKmlPoint destination)
        {
            //
            // All equation numbers refer back to Vincenty's publication:
            // See http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
            //

            // WGS84 Ellipsoid
            double a = 6378137;
            double b = 6356752.3142;
            double f = 1 / 298.257223563;

            // get parameters as radians
            double phi1 = origin.getLatitude().DegreesToRadians();
            double phi2 = destination.getLatitude().DegreesToRadians();
            double lambda1 = origin.getLongitude().DegreesToRadians();
            double lambda2 = destination.getLongitude().DegreesToRadians();

            // calculations
            double a2 = a * a;
            double b2 = b * b;
            double a2b2b2 = (a2 - b2) / b2;

            double omega = lambda2 - lambda1;

            double tanphi1 = Math.Tan(phi1);
            double tanU1 = (1.0 - f) * tanphi1;
            double U1 = Math.Atan(tanU1);
            double sinU1 = Math.Sin(U1);
            double cosU1 = Math.Cos(U1);

            double tanphi2 = Math.Tan(phi2);
            double tanU2 = (1.0 - f) * tanphi2;
            double U2 = Math.Atan(tanU2);
            double sinU2 = Math.Sin(U2);
            double cosU2 = Math.Cos(U2);

            double sinU1sinU2 = sinU1 * sinU2;
            double cosU1sinU2 = cosU1 * sinU2;
            double sinU1cosU2 = sinU1 * cosU2;
            double cosU1cosU2 = cosU1 * cosU2;

            // eq. 13
            double lambda = omega;

            // intermediates we'll need to compute 's'
            double A = 0.0;
            double B = 0.0;
            double sigma = 0.0;
            double deltasigma = 0.0;
            double lambda0;

            for (int i = 0; i < 20; i++)
            {
                lambda0 = lambda;

                double sinlambda = Math.Sin(lambda);
                double coslambda = Math.Cos(lambda);

                // eq. 14
                double sin2sigma = (cosU2 * sinlambda * cosU2 * sinlambda) + Math.Pow(cosU1sinU2 - sinU1cosU2 * coslambda, 2.0);
                double sinsigma = Math.Sqrt(sin2sigma);

                // eq. 15
                double cossigma = sinU1sinU2 + (cosU1cosU2 * coslambda);

                // eq. 16
                sigma = Math.Atan2(sinsigma, cossigma);

                // eq. 17    Careful!  sin2sigma might be almost 0!
                double sinalpha = (sin2sigma == 0) ? 0.0 : cosU1cosU2 * sinlambda / sinsigma;
                double alpha = Math.Asin(sinalpha);
                double cosalpha = Math.Cos(alpha);
                double cos2alpha = cosalpha * cosalpha;

                // eq. 18    Careful!  cos2alpha might be almost 0!
                double cos2sigmam = cos2alpha == 0.0 ? 0.0 : cossigma - 2 * sinU1sinU2 / cos2alpha;
                double u2 = cos2alpha * a2b2b2;

                double cos2sigmam2 = cos2sigmam * cos2sigmam;

                // eq. 3
                A = 1.0 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2)));

                // eq. 4
                B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2)));

                // eq. 6
                deltasigma = B * sinsigma * (cos2sigmam + B / 4 * (cossigma * (-1 + 2 * cos2sigmam2) - B / 6 * cos2sigmam * (-3 + 4 * sin2sigma) * (-3 + 4 * cos2sigmam2)));

                // eq. 10
                double C = f / 16 * cos2alpha * (4 + f * (4 - 3 * cos2alpha));

                // eq. 11 (modified)
                lambda = omega + (1 - C) * f * sinalpha * (sigma + C * sinsigma * (cos2sigmam + C * cossigma * (-1 + 2 * cos2sigmam2)));

                // see how much improvement we got
                double change = Math.Abs((lambda - lambda0) / lambda);

                if ((i > 1) && (change < EPSILON))
                {
                    break;
                }
            }

            // eq. 19
            double s = b * A * (sigma - deltasigma);

            return s;
        }
Esempio n. 7
0
 /// <summary>
 /// Look at the given point
 /// </summary>
 /// <param name="ge">the plugin</param>
 /// <param name="point">the point to look at</param>
 public static void LookAt(IGEPlugin ge, IKmlPoint point)
 {
     LookAt(ge, point.getLatitude(), point.getLongitude());
 }
Esempio n. 8
0
 /*This is called by the Javascript function that will show the ruler point on the map and will do the calculation of distance */
 public void createRulerPoint(IKmlPlacemark rulerPoint, IKmlPoint point)
 {
     IKmlIcon rulerPointIcon = ge.createIcon("");
     rulerPointIcon.setHref("http://maps.google.com/mapfiles/kml/shapes/placemark_square.png");
     IKmlStyle rulerPointStyle = ge.createStyle("");
     rulerPointStyle.getIconStyle().setIcon(rulerPointIcon);
     rulerPoint.setStyleSelector(rulerPointStyle);
     ruler.getFeatures().appendChild(rulerPoint);  // Add the point to the map.
     /*We will then implement the feature that will calculate the distance between the points*/
     linePoints.getCoordinates().pushLatLngAlt(point.getLatitude(), point.getLongitude(), 0);
     line.setGeometry(linePoints);
     if (pointsMeasured != 0)
     {
         //This means this is not the first point we're measuring. Hence we should find out the distance
         //The distance will be the distance measured so far, plus the distance between the last point and the current point
         rulerDistance += Math.Round(DistanceAlgorithm.DistanceBetweenPlaces(lastPoint.getLatitude(), lastPoint.getLongitude(), point.getLatitude(), point.getLongitude()), 2);
         rulerDistanceText.Text = rulerDistance.ToString() + " km";
         ++pointsMeasured;
     }
     else
     {
         ++pointsMeasured;
     }
     lastPoint = point;
 }