Example #1
0
        /**
         * Return true if the edge AB intersects the given edge of constant longitude.
         */

        private static bool IntersectsLngEdge(S2Point a, S2Point b,
                                              R1Interval lat, double lng)
        {
            // Return true if the segment AB intersects the given edge of constant
            // longitude. The nice thing about edges of constant longitude is that
            // they are straight lines on the sphere (geodesics).

            return(S2.SimpleCrossing(a, b, S2LatLng.FromRadians(lat.Lo, lng)
                                     .ToPoint(), S2LatLng.FromRadians(lat.Hi, lng).ToPoint()));
        }
Example #2
0
        public void AddPoint(S2Point b)
        {
            // assert (S2.isUnitLength(b));

            var bLatLng = new S2LatLng(b);

            if (bound.IsEmpty)
            {
                bound = bound.AddPoint(bLatLng);
            }
            else
            {
                // We can't just call bound.addPoint(bLatLng) here, since we need to
                // ensure that all the longitudes between "a" and "b" are included.
                bound = bound.Union(S2LatLngRect.FromPointPair(aLatLng, bLatLng));

                // Check whether the Min/Max latitude occurs in the edge interior.
                // We find the normal to the plane containing AB, and then a vector
                // "dir" in this plane that also passes through the equator. We use
                // RobustCrossProd to ensure that the edge normal is accurate even
                // when the two points are very close together.
                var aCrossB = S2.RobustCrossProd(a, b);
                var dir     = S2Point.CrossProd(aCrossB, new S2Point(0, 0, 1));
                var da      = dir.DotProd(a);
                var db      = dir.DotProd(b);

                if (da * db < 0)
                {
                    // Minimum/maximum latitude occurs in the edge interior. This affects
                    // the latitude bounds but not the longitude bounds.
                    var absLat = Math.Acos(Math.Abs(aCrossB[2] / aCrossB.Norm));
                    var lat    = bound.Lat;
                    if (da < 0)
                    {
                        // It's possible that absLat < lat.lo() due to numerical errors.
                        lat = new R1Interval(lat.Lo, Math.Max(absLat, bound.Lat.Hi));
                    }
                    else
                    {
                        lat = new R1Interval(Math.Min(-absLat, bound.Lat.Lo), lat.Hi);
                    }
                    bound = new S2LatLngRect(lat, bound.Lng);
                }
            }
            a       = b;
            aLatLng = bLatLng;
        }
Example #3
0
        /**
         * Construct a rectangle from minimum and maximum latitudes and longitudes. If
         * lo.Lng > hi.Lng, the rectangle spans the 180 degree longitude line.
         */

        public S2LatLngRect(S2LatLng lo, S2LatLng hi)
        {
            _lat = new R1Interval(lo.Lat.Radians, hi.Lat.Radians);
            _lng = new S1Interval(lo.Lng.Radians, hi.Lng.Radians);
            // assert (isValid());
        }
Example #4
0
        /** Construct a rectangle from latitude and longitude intervals. */

        public S2LatLngRect(R1Interval lat, S1Interval lng)
        {
            _lat = lat;
            _lng = lng;
            // assert (isValid());
        }
Example #5
0
        /**
         * Convenience method to construct the minimal bounding rectangle containing
         * the two given points. This is equivalent to starting with an empty
         * rectangle and calling AddPoint() twice. Note that it is different than the
         * S2LatLngRect(lo, hi) constructor, where the first point is always used as
         * the lower-left corner of the resulting rectangle.
         */

        public static S2LatLngRect FromPointPair(S2LatLng p1, S2LatLng p2)
        {
            // assert (p1.isValid() && p2.isValid());
            return(new S2LatLngRect(R1Interval.FromPointPair(p1.Lat.Radians, p2.Lat.Radians), S1Interval.FromPointPair(p1.Lng.Radians, p2.Lng.Radians)));
        }