public void Filter(ICoordinateSequence seq, int i)
            {
                double x = seq.GetX(i);
                double y = seq.GetY(i);

                if (_ctx.IsGeo() && _normalizeGeomCoords)
                {
                    double xNorm = DistanceUtils.NormLonDEG(x);
                    if (x != xNorm)
                    {
                        changed = true;
                        seq.SetOrdinate(i, Ordinate.X, xNorm);
                    }

                    double yNorm = DistanceUtils.NormLatDEG(y);
                    if (y != yNorm)
                    {
                        changed = true;
                        seq.SetOrdinate(i, Ordinate.Y, yNorm);
                    }
                }
                else
                {
                    _ctx.VerifyX(x);
                    _ctx.VerifyY(y);
                }
            }
示例#2
0
        public NtsGeometry(IGeometry geom, NtsSpatialContext ctx, bool dateline180Check)
        {
            this.ctx = ctx;

            //GeometryCollection isn't supported in relate()
            if (geom.GetType() == typeof(GeometryCollection))
            {
                throw new ArgumentException("NtsGeometry does not support GeometryCollection but does support its subclasses.");
            }

            //NOTE: All this logic is fairly expensive. There are some short-circuit checks though.
            if (ctx.IsGeo())
            {
                //Unwraps the geometry across the dateline so it exceeds the standard geo bounds (-180 to +180).
                if (dateline180Check)
                {
                    UnwrapDateline(geom); //potentially modifies geom
                }
                //If given multiple overlapping polygons, fix it by union
                geom = UnionGeometryCollection(geom); //returns same or new geom
                Envelope unwrappedEnv = geom.EnvelopeInternal;

                //Cuts an unwrapped geometry back into overlaid pages in the standard geo bounds.
                geom = CutUnwrappedGeomInto360(geom);                       //returns same or new geom
                Debug.Assert(geom.EnvelopeInternal.Width <= 360);
                Debug.Assert(geom.GetType() != typeof(GeometryCollection)); //double check

                //note: this bbox may be sub-optimal. If geom is a collection of things near the dateline on both sides then
                // the bbox will needlessly span most or all of the globe longitudinally.
                // TODO so consider using MultiShape's planned minimal geo bounding box algorithm once implemented.
                double envWidth = unwrappedEnv.Width;

                //adjust minX and maxX considering the dateline and world wrap
                double minX, maxX;
                if (envWidth >= 360)
                {
                    minX = -180;
                    maxX = 180;
                }
                else
                {
                    minX = unwrappedEnv.MinX;
                    maxX = DistanceUtils.NormLonDEG(unwrappedEnv.MinX + envWidth);
                }
                bbox = new RectangleImpl(minX, maxX, unwrappedEnv.MinY, unwrappedEnv.MaxY, ctx);
            }
            else
            {//not geo
                Envelope env = geom.EnvelopeInternal;
                bbox = new RectangleImpl(env.MinX, env.MaxX, env.MinY, env.MaxY, ctx);
            }
            var _ = geom.EnvelopeInternal;            //ensure envelope is cached internally, which is lazy evaluated. Keeps this thread-safe.

            //Check geom validity; use helpful error
            // TODO add way to conditionally skip at your peril later
            var isValidOp = new IsValidOp(geom);

            if (!isValidOp.IsValid)
            {
                throw new InvalidShapeException(isValidOp.ValidationError.ToString());
            }
            this.geom = geom;

            this._hasArea = !((geom is ILineal) || (geom is IPuntal));
        }