private void ComputeResult() { var edges = _graph.GetVertexEdges(); foreach (var e in edges) { if (MarkHalfEdge.IsMarked(e)) { continue; } Process(e); } _result = _factory.BuildGeometry(_lines); }
private Geometry ExtractElements(Geometry geom, bool[] interacts, bool isInteracting) { var extractedGeoms = new List <Geometry>(); for (int i = 0; i < geom.NumGeometries; i++) { var elem = geom.GetGeometryN(i); if (interacts[i] == isInteracting) { extractedGeoms.Add(elem); } } return(_geomFactory.BuildGeometry(extractedGeoms)); }
/// <summary> /// Transforms a <see cref="MultiPoint"/> geometry. /// </summary> /// <param name="geom">The <c>MultiPoint</c> to transform</param> /// <param name="parent">The parent geometry</param> /// <returns>A <c>MultiPoint</c></returns> protected virtual Geometry TransformMultiPoint(MultiPoint geom, Geometry parent) { var transGeomList = new List <Geometry>(); for (int i = 0; i < geom.NumGeometries; i++) { var transformGeom = TransformPoint((Point)geom.GetGeometryN(i), geom); if (transformGeom == null) { continue; } if (transformGeom.IsEmpty) { continue; } transGeomList.Add(transformGeom); } if (transGeomList.Count == 0) { return(Factory.CreateMultiPoint()); } return(Factory.BuildGeometry(transGeomList)); }
private Geometry Select(Geometry geoms, int n) { var selection = new List <Geometry>(); // add all the geometries for (int i = 0; i < geoms.NumGeometries; i++) { selection.Add(geoms.GetGeometryN(i)); } // toss out random ones to leave n while (selection.Count > n) { int index = (int)(selection.Count * Rnd.NextDouble()); selection.RemoveAt(index); } return(_geomFact.BuildGeometry(selection)); }
private Geometry ComputeGeometry(IEnumerable <Geometry> resultPtList, IEnumerable <Geometry> resultLiList, IEnumerable <Geometry> resultPlList, SpatialFunction opCode) { var geomList = new List <Geometry>(); // element geometries of the result are always in the order Point,Curve,A geomList.AddRange(resultPtList); geomList.AddRange(resultLiList); geomList.AddRange(resultPlList); if (geomList.Count == 0) { return(CreateEmptyResult(opCode, arg[0].Geometry, arg[1].Geometry, _geomFact)); } // build the most specific point possible return(_geomFact.BuildGeometry(geomList)); }
private Geometry ExtractByEnvelope(Envelope env, Geometry geom, IList <Geometry> disjointGeoms) { var intersectingGeoms = new List <Geometry>(); for (int i = 0; i < geom.NumGeometries; i++) { var elem = geom.GetGeometryN(i); if (elem.EnvelopeInternal.Intersects(env)) { intersectingGeoms.Add(elem); } else { disjointGeoms.Add(elem); } } return(_geomFactory.BuildGeometry(intersectingGeoms)); }
internal static Geometry ToLines(OverlayGraph graph, bool isOutputEdges, GeometryFactory geomFact) { var lines = new List <LineString>(); foreach (var edge in graph.Edges) { bool includeEdge = isOutputEdges || edge.IsInResultArea; if (!includeEdge) { continue; } //Coordinate[] pts = getCoords(nss); var pts = edge.CoordinatesOriented; var line = geomFact.CreateLineString(pts); line.UserData = LabelForResult(edge); lines.Add(line); } return(geomFact.BuildGeometry(lines)); }
public virtual Geometry Buffer(Geometry g, double distance) { PrecisionModel precisionModel = workingPrecisionModel; if (precisionModel == null) precisionModel = g.PrecisionModel; // factory must be the same as the one used by the input geomFact = g.Factory; OffsetCurveBuilder curveBuilder = new OffsetCurveBuilder(precisionModel, quadrantSegments); curveBuilder.EndCapStyle = endCapStyle; OffsetCurveSetBuilder curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder); ArrayList bufferSegStrList = curveSetBuilder.Curves; // short-circuit test if (bufferSegStrList.Count <= 0) { Geometry emptyGeom = geomFact.CreateGeometryCollection(new Geometry[0]); return emptyGeom; } ComputeNodedEdges(bufferSegStrList, precisionModel); graph = new PlanarGraph(new OverlayNodeFactory()); graph.AddEdges(edgeList.Edges); IList subgraphList = CreateSubgraphs(graph); PolygonBuilder polyBuilder = new PolygonBuilder(geomFact); BuildSubgraphs(subgraphList, polyBuilder); GeometryList resultPolyList = polyBuilder.Build(); Geometry resultGeom = geomFact.BuildGeometry(resultPolyList); return resultGeom; }
private static Geometry ExtractLines(ICollection <Geometry> geoms) { GeometryFactory factory = null; var lines = new List <Geometry>(); foreach (var g in geoms) { if (factory == null) { factory = g.Factory; } var coll = LinearComponentExtracter.GetLines(g); lines.AddRange(coll); } if (factory == null) { return(null); } return(factory.BuildGeometry(geoms)); }
/// <summary> /// Computes the combination of the input geometries to produce the most appropriate <see cref="Geometry"/> or <see cref="GeometryCollection"/> /// </summary> /// <returns>A Geometry which is the combination of the inputs</returns> /// <returns></returns> public Geometry Combine() { var elems = new List <Geometry>(); bool first = true; GeometryFactory geomFactory = null; foreach (var geom in _inputGeoms) { if (first) { geomFactory = geom.Factory; first = false; } ExtractElements(geom, elems); } if (elems.Count == 0) { return(geomFactory?.CreateGeometryCollection()); } return(geomFactory.BuildGeometry(elems)); }
/// <summary> /// Creates an overlay result geometry for homogeneous or mixed components. /// </summary> /// <param name="resultPolyList">An enumeration of result polygons (may be empty or <c>null</c>)</param> /// <param name="resultLineList">An enumeration of result lines (may be empty or <c>null</c>)</param> /// <param name="resultPointList">An enumeration of result points (may be empty or <c>null</c>)</param> /// <param name="geometryFactory">The geometry factory to use.</param> /// <returns>A geometry structured according to the overlay result semantics</returns> internal static Geometry CreateResultGeometry(IEnumerable <Polygon> resultPolyList, IEnumerable <LineString> resultLineList, IEnumerable <Point> resultPointList, GeometryFactory geometryFactory) { var geomList = new List <Geometry>(); // TODO: for mixed dimension, return collection of Multigeom for each dimension (breaking change) // element geometries of the result are always in the order A,L,P if (resultPolyList != null) { geomList.AddRange(resultPolyList); } if (resultLineList != null) { geomList.AddRange(resultLineList); } if (resultPointList != null) { geomList.AddRange(resultPointList); } // build the most specific geometry possible // TODO: perhaps do this internally to give more control? return(geometryFactory.BuildGeometry(geomList)); }
/// <summary> /// Builds a geometry (<see cref="LineString" /> or <see cref="MultiLineString" />) /// representing the sequence. /// </summary> /// <param name="sequences"> /// An enumeration of <see cref="IList{DirectedEdge}" />s of <see cref="DirectedEdge" />s /// with <see cref="LineMergeEdge" />s as their parent edges. /// </param> /// <returns> /// The sequenced geometry, or <c>null</c> if no sequence exists. /// </returns> private Geometry BuildSequencedGeometry(IEnumerable <IEnumerable <DirectedEdge> > sequences) { var lines = new List <Geometry>(); foreach (IList <DirectedEdge> seq in sequences) { foreach (var de in seq) { var e = (LineMergeEdge)de.Edge; var line = e.Line; var lineToAdd = line; if (!de.EdgeDirection && !line.IsClosed) { lineToAdd = Reverse(line); } lines.Add(lineToAdd); } } return(lines.Count == 0 ? _factory.CreateMultiLineString(new LineString[] { }) : _factory.BuildGeometry(lines)); }
/// <summary> /// Builds and returns the <see cref="Geometry" />. /// </summary> /// <returns></returns> public Geometry GetGeometry() { // end last line in case it was not done by user EndLine(); return(_geomFact.BuildGeometry(_lines)); }
private Geometry ComputeGeometry(ArrayList resultPolyList) { return(_geomFact.BuildGeometry(resultPolyList)); }
/// <summary> /// Gets a NTS <see cref="IGeometry"/> for the given <see cref="IShape"/>. Some shapes hold a /// NTS geometry whereas new ones must be created for the rest. /// </summary> /// <param name="shape">Not null</param> /// <returns>Not null</returns> public virtual IGeometry GetGeometryFrom(IShape shape) { if (shape is NtsGeometry) { return(((NtsGeometry)shape).Geometry); } if (shape is NtsPoint) { return(((NtsPoint)shape).Geometry); } var point = shape as Shapes.IPoint; if (point != null) { return(m_geometryFactory.CreatePoint(new Coordinate(point.X, point.Y))); } var r = shape as IRectangle; if (r != null) { if (r.CrossesDateLine) { var pair = new List <IGeometry>(2) { m_geometryFactory.ToGeometry(new Envelope( r.MinX, WorldBounds.MaxX, r.MinY, r.MaxY)), m_geometryFactory.ToGeometry(new Envelope( WorldBounds.MinX, r.MaxX, r.MinY, r.MaxY)) }; return(m_geometryFactory.BuildGeometry(pair));//a MultiPolygon or MultiLineString } else { return(m_geometryFactory.ToGeometry(new Envelope(r.MinX, r.MaxX, r.MinY, r.MaxY))); } } var circle = shape as ICircle; if (circle != null) { // TODO, this should maybe pick a bunch of points // and make a circle like: // http://docs.codehaus.org/display/GEOTDOC/01+How+to+Create+a+Geometry#01HowtoCreateaGeometry-CreatingaCircle // If this crosses the dateline, it could make two parts // is there an existing utility that does this? if (circle.BoundingBox.CrossesDateLine) { throw new ArgumentException("Doesn't support dateline cross yet: " + circle);//TODO } var gsf = new GeometricShapeFactory(m_geometryFactory) { Size = circle.BoundingBox.Width / 2.0f, NumPoints = 4 * 25,//multiple of 4 is best Centre = new Coordinate(circle.Center.X, circle.Center.Y) }; return(gsf.CreateCircle()); } throw new InvalidShapeException("can't make Geometry from: " + shape); }
/// <summary> /// Gets the union of the input geometries. /// <para/> /// The result of empty input is determined as follows: /// <list type="Bullet"> /// <item><description>If the input is empty and a dimension can be /// determined (i.e. an empty geometry is present), /// an empty atomic geometry of that dimension is returned.</description></item> /// <item><description>If no input geometries were provided but a <see cref="GeometryFactory"/> was provided, /// an empty <see cref="GeometryCollection"/> is returned.</description></item> /// <item><description>Otherwise, the return value is <c>null</c>.</description></item> /// </list> /// </summary> /// <returns> /// A Geometry containing the union, /// or an empty atomic geometry, or an empty <c>GEOMETRYCOLLECTION</c>, /// or<c>null</c> if no GeometryFactory was provided /// </returns> public Geometry Union() { if (_geomFact == null) { _geomFact = _extracter.Factory; } // Case 3 if (_geomFact == null) { return(null); } // Case 1 & 2 if (_extracter.IsEmpty) { return(_geomFact.CreateEmpty(_extracter.Dimension)); } var points = _extracter.GetExtract(Dimension.Point); var lines = _extracter.GetExtract(Dimension.Curve); var polygons = _extracter.GetExtract(Dimension.Surface); /** * For points and lines, only a single union operation is * required, since the OGC model allows self-intersecting * MultiPoint and MultiLineStrings. * This is not the case for polygons, so Cascaded Union is required. */ Geometry unionPoints = null; if (points.Count > 0) { var ptGeom = _geomFact.BuildGeometry(points); unionPoints = UnionNoOpt(ptGeom); } Geometry unionLines = null; if (lines.Count > 0) { var lineGeom = _geomFact.BuildGeometry(lines); unionLines = UnionNoOpt(lineGeom); } Geometry unionPolygons = null; if (polygons.Count > 0) { unionPolygons = CascadedPolygonUnion.Union(polygons); } /* * Performing two unions is somewhat inefficient, * but is mitigated by unioning lines and points first */ var unionLA = UnionWithNull(unionLines, unionPolygons); Geometry union; if (unionPoints == null) { union = unionLA; } else if (unionLA == null) { union = unionPoints; } else { union = PointGeometryUnion.Union((IPuntal)unionPoints, unionLA); } if (union == null) { return(_geomFact.CreateGeometryCollection()); } return(union); }
private static IGeometry LoadData(String file) { var geoms = LoadWKT(file); return(geomFact.BuildGeometry(geoms)); }
/** * The method makes sure that outer and inner rings form valid LinearRings. * <p> * If outerRing is not a valid LinearRing, every linear component is * considered as a degenerated geometry of lower dimension (0 or 1) * </p> * <p> * If outerRing is a valid LinearRing but some innerRings are not, invalid * innerRings are transformed into LineString (or Point) and the returned * geometry may be a GeometryCollection of heterogeneous dimension. * </p> * * @param polygon simple Polygon to make valid * @return a Geometry which may not be a Polygon if the source Polygon is * invalid */ private NetTopologySuite.Geometries.Geometry makePolygonComponentsValid(Polygon polygon) { GeometryFactory factory = polygon.Factory; CoordinateSequence outerRingSeq = makeSequenceValid(polygon.ExteriorRing.CoordinateSequence, false, true); // The validated sequence of the outerRing does not form a valid LinearRing // -> build valid 0-dim or 1-dim geometry from all the rings if (outerRingSeq.Count == 0 || outerRingSeq.Count < 4) { List <NetTopologySuite.Geometries.Geometry> list = new(); if (outerRingSeq.Count > 0) { list.Add(makeLineStringValid(polygon.ExteriorRing)); } for (int i = 0; i < polygon.NumInteriorRings; i++) { NetTopologySuite.Geometries.Geometry g = makeLineStringValid(polygon.GetInteriorRingN(i)); if (!g.IsEmpty) { list.Add(g); } } if (0 == list.Count) { return(factory.CreatePolygon(outerRingSeq)); } else { return(factory.BuildGeometry(list)); } } // OuterRing forms a valid ring. // Inner rings may be degenerated else { List <LinearRing> innerRings = new(); List <NetTopologySuite.Geometries.Geometry> degeneratedRings = new(); for (int i = 0; i < polygon.NumInteriorRings; i++) { CoordinateSequence seq = makeSequenceValid(polygon.GetInteriorRingN(i).CoordinateSequence, false, true); if (seq.Count > 3) { innerRings.Add(factory.CreateLinearRing(seq)); } else if (seq.Count > 1) { degeneratedRings.Add(factory.CreateLineString(seq)); } else if (seq.Count == 1) { degeneratedRings.Add(factory.CreatePoint(seq)); } // seq.size == 0 } Polygon poly = factory.CreatePolygon(factory.CreateLinearRing(outerRingSeq), innerRings.ToArray()); if (0 == degeneratedRings.Count) { return(poly); } else { degeneratedRings.Insert(0, poly); return(factory.BuildGeometry(degeneratedRings)); } } }