// Checked vs. Jan 11, 2011 /// <summary>Sets the envelope of the Geometry.</summary> /// <remarks> /// Sets the envelope of the Geometry. The Envelope description must match /// that of the Geometry. /// </remarks> public virtual void SetEnvelope(com.epl.geometry.Envelope env) { if (!m_description.Equals(env.GetDescription())) { throw new System.ArgumentException(); } // m_envelope = (Envelope) env.clone(); m_envelope = (com.epl.geometry.Envelope)env.CreateInstance(); env.CopyTo(m_envelope); _setDirtyFlag(com.epl.geometry.MultiVertexGeometryImpl.DirtyFlags.DirtyIntervals, false); }
public virtual void TestEnvelope() { com.epl.geometry.Envelope env = new com.epl.geometry.Envelope(); env.SetCoords(100, 200, 250, 300); NUnit.Framework.Assert.IsFalse(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M)); env.AddAttribute(com.epl.geometry.VertexDescription.Semantics.M); NUnit.Framework.Assert.IsTrue(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M)); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.M, 0).IsEmpty()); env.SetInterval(com.epl.geometry.VertexDescription.Semantics.M, 0, 1, 2); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.M, 0).vmin == 1); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.M, 0).vmax == 2); NUnit.Framework.Assert.IsFalse(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z)); env.AddAttribute(com.epl.geometry.VertexDescription.Semantics.Z); NUnit.Framework.Assert.IsTrue(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z)); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmin == 0); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmax == 0); env.SetInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0, 3, 4); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmin == 3); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmax == 4); NUnit.Framework.Assert.IsFalse(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.ID)); env.AddAttribute(com.epl.geometry.VertexDescription.Semantics.ID); NUnit.Framework.Assert.IsTrue(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.ID)); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmin == 0); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmax == 0); env.SetInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0, 5, 6); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmin == 5); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmax == 6); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmin == 3); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmax == 4); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.M, 0).vmin == 1); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.M, 0).vmax == 2); env.DropAttribute(com.epl.geometry.VertexDescription.Semantics.M); NUnit.Framework.Assert.IsFalse(env.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M)); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmin == 5); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmax == 6); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmin == 3); NUnit.Framework.Assert.IsTrue(env.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmax == 4); com.epl.geometry.Envelope env1 = new com.epl.geometry.Envelope(); env.CopyTo(env1); NUnit.Framework.Assert.IsFalse(env1.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M)); NUnit.Framework.Assert.IsTrue(env1.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmin == 5); NUnit.Framework.Assert.IsTrue(env1.QueryInterval(com.epl.geometry.VertexDescription.Semantics.ID, 0).vmax == 6); NUnit.Framework.Assert.IsTrue(env1.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmin == 3); NUnit.Framework.Assert.IsTrue(env1.QueryInterval(com.epl.geometry.VertexDescription.Semantics.Z, 0).vmax == 4); }
// note: overload for polylines/polygons with curves // Checked vs. Jan 11, 2011 public override void QueryEnvelope(com.epl.geometry.Envelope env) { _updateAllDirtyIntervals(true); m_envelope.CopyTo(env); }
internal virtual com.epl.geometry.Geometry TryNativeImplementation_(com.epl.geometry.Geometry input_geom) { // A note on attributes: // 1. The geometry with lower dimension wins in regard to the // attributes. // 2. If the dimensions are the same, the input_geometry attributes win. // 3. The exception to the 2. is when the input is an Envelope, and the // intersector is a polygon, then the intersector wins. // A note on the tolerance: // This operator performs a simple intersection operation. Should it use // the tolerance? // Example: Point is intersected by the envelope. // If it is slightly outside of the envelope, should we still return it // if it is closer than the tolerance? // Should we do crack and cluster and snap the point coordinates to the // envelope boundary? // // Consider floating point arithmetics approach. When you compare // doubles, you should use an epsilon (equals means ::fabs(a - b) < // eps), however when you add/subtract, etc them, you do not use // epsilon. // Shouldn't we do same here? Relational operators use tolerance, but // the action operators don't. com.epl.geometry.Envelope2D mergedExtent = com.epl.geometry.InternalUtils.GetMergedExtent(input_geom, m_geomIntersector); double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, mergedExtent, false); int gtInput = input_geom.GetType().Value(); bool bInputEmpty = input_geom.IsEmpty(); bool bGeomIntersectorEmpty = m_geomIntersector.IsEmpty(); bool bResultIsEmpty = bInputEmpty || bGeomIntersectorEmpty; if (!bResultIsEmpty) { // test envelopes com.epl.geometry.Envelope2D env2D1 = new com.epl.geometry.Envelope2D(); input_geom.QueryEnvelope2D(env2D1); com.epl.geometry.Envelope2D env2D2 = new com.epl.geometry.Envelope2D(); m_geomIntersector.QueryEnvelope2D(env2D2); env2D2.Inflate(2.0 * tolerance, 2.0 * tolerance); bResultIsEmpty = !env2D1.IsIntersecting(env2D2); } if (!bResultIsEmpty) { // try accelerated test int res = com.epl.geometry.OperatorInternalRelationUtils.QuickTest2D_Accelerated_DisjointOrContains(m_geomIntersector, input_geom, tolerance); if (res == com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint) { // disjoint bResultIsEmpty = true; } else { if ((res & com.epl.geometry.OperatorInternalRelationUtils.Relation.Within) != 0) { // intersector // is // within // the // input_geom // TODO: // assign // input_geom // attributes // first return m_geomIntersector; } else { if ((res & com.epl.geometry.OperatorInternalRelationUtils.Relation.Contains) != 0) { // intersector // contains // input_geom return input_geom; } } } } if (bResultIsEmpty) { // When one geometry or both are empty, we need to // return an empty geometry. // Here we do that end also ensure the type is // correct. // That is the lower dimension need to be // returned. Also, for Point vs Multi_point, an // empty Point need to be returned. int dim1 = com.epl.geometry.Geometry.GetDimensionFromType(gtInput); int dim2 = com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType); if (dim1 < dim2) { return ReturnEmpty_(input_geom, bInputEmpty); } else { if (dim1 > dim2) { return ReturnEmptyIntersector_(); } else { if (dim1 == 0) { if (gtInput == com.epl.geometry.Geometry.GeometryType.MultiPoint && m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Point) { // point // vs // Multi_point // need // special // treatment // to // ensure // Point // is // returned // always. return ReturnEmptyIntersector_(); } else { // Both input and intersector have same gtype, or input is // Point. return ReturnEmpty_(input_geom, bInputEmpty); } } else { return ReturnEmpty_(input_geom, bInputEmpty); } } } } // Note: No empty geometries after this point! // Warning: Do not try clip for polylines and polygons. // Try clip of Envelope with Envelope. if ((m_dimensionMask == -1 || m_dimensionMask == (1 << 2)) && gtInput == com.epl.geometry.Geometry.GeometryType.Envelope && m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Envelope) { com.epl.geometry.Envelope env1 = (com.epl.geometry.Envelope)input_geom; com.epl.geometry.Envelope env2 = (com.epl.geometry.Envelope)m_geomIntersector; com.epl.geometry.Envelope2D env2D_1 = new com.epl.geometry.Envelope2D(); env1.QueryEnvelope2D(env2D_1); com.epl.geometry.Envelope2D env2D_2 = new com.epl.geometry.Envelope2D(); env2.QueryEnvelope2D(env2D_2); env2D_1.Intersect(env2D_2); com.epl.geometry.Envelope result_env = new com.epl.geometry.Envelope(); env1.CopyTo(result_env); result_env.SetEnvelope2D(env2D_1); return result_env; } // Use clip for Point and Multi_point with Envelope if ((gtInput == com.epl.geometry.Geometry.GeometryType.Envelope && com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType) == 0) || (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Envelope && com.epl.geometry.Geometry.GetDimensionFromType(gtInput ) == 0)) { com.epl.geometry.Envelope env = gtInput == com.epl.geometry.Geometry.GeometryType.Envelope ? (com.epl.geometry.Envelope)input_geom : (com.epl.geometry.Envelope)m_geomIntersector; com.epl.geometry.Geometry other = gtInput == com.epl.geometry.Geometry.GeometryType.Envelope ? m_geomIntersector : input_geom; com.epl.geometry.Envelope2D env_2D = new com.epl.geometry.Envelope2D(); env.QueryEnvelope2D(env_2D); return com.epl.geometry.Clipper.Clip(other, env_2D, tolerance, 0); } if ((com.epl.geometry.Geometry.GetDimensionFromType(gtInput) == 0 && com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType) > 0) || (com.epl.geometry.Geometry.GetDimensionFromType(gtInput) > 0 && com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType ) == 0)) { // multipoint // intersection double tolerance1 = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, input_geom, false); if (gtInput == com.epl.geometry.Geometry.GeometryType.MultiPoint) { return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.MultiPoint)input_geom, m_geomIntersector, tolerance1); } if (gtInput == com.epl.geometry.Geometry.GeometryType.Point) { return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.Point)input_geom, m_geomIntersector, tolerance1); } if (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.MultiPoint) { return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.MultiPoint)m_geomIntersector, input_geom, tolerance1); } if (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Point) { return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.Point)m_geomIntersector, input_geom, tolerance1); } throw com.epl.geometry.GeometryException.GeometryInternalError(); } // Try Polyline vs Polygon if ((m_dimensionMask == -1 || m_dimensionMask == (1 << 1)) && (gtInput == com.epl.geometry.Geometry.GeometryType.Polyline) && (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Polygon)) { return TryFastIntersectPolylinePolygon_((com.epl.geometry.Polyline)(input_geom), (com.epl.geometry.Polygon)(m_geomIntersector)); } // Try Polygon vs Polyline if ((m_dimensionMask == -1 || m_dimensionMask == (1 << 1)) && (gtInput == com.epl.geometry.Geometry.GeometryType.Polygon) && (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Polyline)) { return TryFastIntersectPolylinePolygon_((com.epl.geometry.Polyline)(m_geomIntersector), (com.epl.geometry.Polygon)(input_geom)); } return null; }