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); } }
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)); }