/// <summary> /// /// </summary> /// <param name="opCode"></param> private void ComputeOverlay(SpatialFunction opCode) { // copy points from input Geometries. // This ensures that any Point geometries // in the input are considered for inclusion in the result set CopyPoints(0); CopyPoints(1); // node the input Geometries Arg[0].ComputeSelfNodes(LineIntersector, false); Arg[1].ComputeSelfNodes(LineIntersector, false); // --- Needs to convert args to monotonic edges or something. // compute intersections between edges of the two input geometries Arg[0].ComputeEdgeIntersections(Arg[1], LineIntersector, true); IList baseSplitEdges = new ArrayList(); Arg[0].ComputeSplitEdges(baseSplitEdges); Arg[1].ComputeSplitEdges(baseSplitEdges); // add the noded edges to this result graph InsertUniqueEdges(baseSplitEdges); ComputeLabelsFromDepths(); ReplaceCollapsedEdges(); _graph.AddEdges(_edgeList.Edges); ComputeLabelling(); LabelIncompleteNodes(); /* * The ordering of building the result Geometries is important. * Areas must be built before lines, which must be built before points. * This is so that lines which are covered by areas are not included * explicitly, and similarly for points. */ FindResultAreaEdges(opCode); CancelDuplicateResultEdges(); PolygonBuilder polyBuilder = new PolygonBuilder(_geomFact); polyBuilder.Add(_graph); _resultPolyList = polyBuilder.Polygons; LineBuilder lineBuilder = new LineBuilder(this, _geomFact, _ptLocator); _resultLineList = lineBuilder.Build(opCode); PointBuilder pointBuilder = new PointBuilder(this, _geomFact); _resultPointList = pointBuilder.Build(opCode); // gather the results from all calculations into a single Geometry for the result set _resultGeom = ComputeGeometry(_resultPointList, _resultLineList, _resultPolyList); }
/// <summary> /// /// </summary> /// <param name="g"></param> /// <param name="distance"></param> /// <returns></returns> public IGeometry Buffer(IGeometry g, double distance) { PrecisionModel precisionModel = _workingPrecisionModel ?? new 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); IList bufferSegStrList = curveSetBuilder.GetCurves(); // short-circuit test if (bufferSegStrList.Count <= 0) { IGeometry 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); IList resultPolyList = polyBuilder.Polygons; IGeometry resultGeom = _geomFact.BuildGeometry(resultPolyList); return resultGeom; }
/// <summary> /// Completes the building of the input subgraphs by depth-labelling them, /// and adds them to the <see cref="PolygonBuilder" />. /// The subgraph list must be sorted in rightmost-coordinate order. /// </summary> /// <param name="subgraphList">The subgraphs to build.</param> /// <param name="polyBuilder">The PolygonBuilder which will build the final polygons.</param> private static void BuildSubgraphs(IList subgraphList, PolygonBuilder polyBuilder) { IList processedGraphs = new ArrayList(); foreach (object obj in subgraphList) { BufferSubgraph subgraph = (BufferSubgraph)obj; Coordinate p = subgraph.RightMostCoordinate; SubgraphDepthLocater locater = new SubgraphDepthLocater(processedGraphs); int outsideDepth = locater.GetDepth(p); subgraph.ComputeDepth(outsideDepth); subgraph.FindResultEdges(); processedGraphs.Add(subgraph); polyBuilder.Add(subgraph.DirectedEdges, subgraph.Nodes); } }