示例#1
0
        private bool CutFeature([NotNull] IFeature feature,
                                [NotNull] IPolyline cutPolyline,
                                ChangeAlongZSource?zSource = null)
        {
            IGeometry selectedGeometry = feature.Shape;

            if (GeometryUtils.Disjoint(cutPolyline, selectedGeometry))
            {
                return(false);
            }

            if (FeatureToCutPredicate != null &&
                !FeatureToCutPredicate(selectedGeometry, cutPolyline))
            {
                return(false);
            }

            _msg.DebugFormat("Cutting feature {0}", GdbObjectUtils.ToString(feature));

            IGeometry geometryToCut = GeometryFactory.Clone(selectedGeometry);

            CutPolyline usedCutLine = null;

            if (ProcessedCutLines != null)
            {
                usedCutLine = new CutPolyline(feature.OID);
                ProcessedCutLines.Add(usedCutLine);
            }

            IList <IGeometry> resultGeometries;

            switch (geometryToCut.GeometryType)
            {
            case esriGeometryType.esriGeometryPolygon:
                resultGeometries = CutGeometryUtils.TryCut(
                    (IPolygon)geometryToCut, cutPolyline,
                    zSource ?? DetermineZSource(feature));
                break;

            case esriGeometryType.esriGeometryPolyline:
                resultGeometries =
                    _networkFeatureCutter?.IsNetworkEdge(feature) == true
                                                        ? GetNetworkSplitPoints(cutPolyline, geometryToCut)
                                                        : CutGeometryUtils.TryCut((IPolyline)geometryToCut, cutPolyline);

                break;

            case esriGeometryType.esriGeometryMultiPatch:
                resultGeometries =
                    CutGeometryUtils.TryCut((IMultiPatch)geometryToCut, cutPolyline,
                                            zSource ?? DetermineZSource(feature),
                                            usedCutLine, DegenerateMultipatchFootprintAction)
                    .Values.Cast <IGeometry>()
                    .ToList();
                break;

            default:
                throw new InvalidOperationException(
                          $"Unsupported geometry type: {geometryToCut.GeometryType}");
            }

            if (resultGeometries != null && resultGeometries.Count > 0)
            {
                IList <IGeometry> previousResults;
                if (ResultGeometriesByFeature.TryGetValue(feature, out previousResults))
                {
                    foreach (IGeometry resultGeometry in resultGeometries)
                    {
                        previousResults.Add(resultGeometry);
                    }
                }
                else
                {
                    ResultGeometriesByFeature.Add(feature, resultGeometries);
                }
            }

            return(resultGeometries != null && resultGeometries.Count > 0);
        }
示例#2
0
        private void CutFeature3D(IFeature feature, IMultiPatch cutSurfaces)
        {
            IGeometry selectedGeometry = feature.Shape;

            if (GeometryUtils.Disjoint(cutSurfaces, selectedGeometry))
            {
                return;
            }

            if (GeometryUtils.AreEqual(cutSurfaces, selectedGeometry))
            {
                return;
            }

            if (FeatureToCutPredicate != null &&
                !FeatureToCutPredicate(selectedGeometry, cutSurfaces))
            {
                return;
            }

            // TODO: Multipatches should be cut if its footprint can be cut. However, if multiple ring groups exist,
            //       that are not connected (touch along a line) in 3D, the rings should be grouped into connected parts.

            List <CutPolyline> cutPolylines =
                IntersectionUtils.GetIntersectionLines3D((IMultiPatch)selectedGeometry,
                                                         cutSurfaces).ToList();

            foreach (CutPolyline cutPoline in cutPolylines)
            {
                cutPoline.ObjectId = feature.OID;

                // Add the calculated lines for reference and traceability, filtering and subsequent cutting
                // with Success field equals null
                ProcessedCutLines?.Add(cutPoline);
            }

            if (cutPolylines.Count > 0)
            {
                var success = false;

                // TODO: Consider filter option for cut lines or even a clever path selection logic to avoid junctions:
                // Only use cut lines that are in the plane to connect disjoint cut line paths that are positive or negative
                // Consider adding an option to delete the negative or the positive side of the rings.

                var cutLineToUse =
                    (IPolyline)GeometryUtils.Union(
                        cutPolylines.Select(c => c.Polyline).ToList());
                GeometryUtils.Simplify(cutLineToUse, true, false);

                if (!cutLineToUse.IsEmpty)
                {
                    try
                    {
                        success = CutFeature(feature, cutLineToUse,
                                             ChangeAlongZSource.SourcePlane);
                    }
                    catch (Exception e)
                    {
                        _msg.WarnFormat("Cutting multipatch feature {0} failed.",
                                        GdbObjectUtils.ToString(feature));
                        _msg.Debug(e);
                    }

                    var appliedCutline = new CutPolyline(cutLineToUse);
                    appliedCutline.SuccessfulCut = success;

                    ProcessedCutLines?.Add(appliedCutline);
                }
            }
        }