private IEnumerable <Feature> ShatterTwoFeatures(ref Feature feature1, Feature feature2) { Collection <Feature> resultFeatures = new Collection <Feature>(); var columns = GetColumnValues(feature1, feature2); // var diff1 = feature1.GetDifference(feature2); feature1 = SqlTypesGeometryHelper.MakeValid(feature1); feature2 = SqlTypesGeometryHelper.MakeValid(feature2); var diff1 = SqlTypesGeometryHelper.GetDifference(feature1, feature2); //var diff2 = feature2.GetDifference(feature1); var diff2 = SqlTypesGeometryHelper.GetDifference(feature2, feature1); //var inter = feature1.GetIntersection(feature2); var inter = SqlTypesGeometryHelper.GetIntersection(feature1, feature2); feature1 = diff1; if (inter != null) { inter = new Feature(inter.GetWellKnownBinary(), inter.Id, columns); AddValidFeature(resultFeatures, inter); } if (diff2 != null) { AddValidFeature(resultFeatures, diff2); } return(resultFeatures); }
private IEnumerable <Feature> InverseClip(FeatureLayer featureLayer, IEnumerable <Feature> clippingFeatures) { lock (featureLayer) { if (!featureLayer.IsOpen) { featureLayer.Open(); } Collection <Feature> results = featureLayer.FeatureSource.GetFeaturesOutsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(clippingFeatures), featureLayer.GetDistinctColumnNames()); Collection <Feature> sourceFeatures = new Collection <Feature>(); SimpleShapeType simpleShapeType = GisEditor.LayerManager.GetFeatureSimpleShapeType(featureLayer); int index = 1; if (simpleShapeType == SimpleShapeType.Point) { featureLayer.Open(); Collection <Feature> allFeatures = featureLayer.FeatureSource.GetAllFeatures(featureLayer.GetDistinctColumnNames()); featureLayer.Close(); foreach (Feature f in results) { allFeatures.Remove(f); } foreach (var f in InverseClipPoints(allFeatures, clippingFeatures, simpleShapeType)) { results.Add(f); } } else if (simpleShapeType == SimpleShapeType.Line) { bool isOpen = false; Proj4ProjectionInfo projectionInfo = featureLayer.GetProj4ProjectionInfo(); //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures)); List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(clippingFeatures) .Select(f => f.GetShape()) .OfType <AreaBaseShape>() .ToList(); MultipolygonShape areaBaseShape = AreaBaseShape.Union(clippingAreaShapes); if (projectionInfo != null && projectionInfo.CanProject) { if (featureLayer.IsOpen) { featureLayer.Close(); projectionInfo.Close(); isOpen = true; } featureLayer.FeatureSource.Projection = null; } featureLayer.Open(); featureLayer.FeatureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), featureLayer.GetDistinctColumnNames()).ForEach(f => { if (!areaBaseShape.Contains(f)) { sourceFeatures.Add(f); } }); int count = sourceFeatures.Count; if (projectionInfo != null) { featureLayer.FeatureSource.Projection = projectionInfo.Projection; if (isOpen) { featureLayer.Open(); } } if (featureLayer.IsOpen) { featureLayer.Close(); } foreach (var feature in sourceFeatures) { isCanceled = ReportProgress(index, count); if (isCanceled) { break; } index++; try { //if (areaBaseShape.IsDisjointed(feature)) if (SqlTypesGeometryHelper.IsDisjointed(areaBaseShape, feature)) { results.Add(feature); } else { MultilineShape multiLine = (MultilineShape)feature.GetShape(); MultilineShape resultShape = new MultilineShape(); foreach (LineShape lineShape in multiLine.Lines) { //if (areaBaseShape.IsDisjointed(lineShape)) if (SqlTypesGeometryHelper.IsDisjointed(areaBaseShape, lineShape)) { resultShape.Lines.Add(lineShape); } else { var resultLine = lineShape.GetDifference(areaBaseShape); foreach (var line in resultLine.Lines) { resultShape.Lines.Add(line); } } } if (resultShape != null && resultShape.Lines.Count > 0) { results.Add(new Feature(resultShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } } catch (Exception ex) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); HandleExceptionFromInvalidFeature(feature.Id, ex.Message); } } } else if (simpleShapeType == SimpleShapeType.Area) { //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures)); List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(clippingFeatures) .Select(f => f.GetShape()) .OfType <AreaBaseShape>() .ToList(); BaseShape unionResultShape = SqlTypesGeometryHelper.Union(clippingAreaShapes); MultipolygonShape areaBaseShape = ConvertSqlQueryResultToMultiPolygonShape(unionResultShape); bool isOpen = false; Proj4ProjectionInfo projectionInfo = featureLayer.GetProj4ProjectionInfo(); if (projectionInfo != null && projectionInfo.CanProject) { if (featureLayer.IsOpen) { featureLayer.Close(); if (projectionInfo != null) { projectionInfo.Close(); } isOpen = true; } featureLayer.FeatureSource.Projection = null; } if (!featureLayer.IsOpen) { featureLayer.Open(); } featureLayer.FeatureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), featureLayer.GetDistinctColumnNames()).ForEach(f => sourceFeatures.Add(f)); if (featureLayer.IsOpen) { featureLayer.Close(); } if (projectionInfo != null) { featureLayer.FeatureSource.Projection = projectionInfo.Projection; if (isOpen) { featureLayer.Open(); } } int count = sourceFeatures.Count; foreach (var feature in sourceFeatures) { isCanceled = ReportProgress(index, count); if (isCanceled) { break; } index++; try { //if (areaBaseShape.IsDisjointed(feature)) if (SqlTypesGeometryHelper.IsDisjointed(areaBaseShape, feature)) { results.Add(feature); } else { //var clippedShape = ((AreaBaseShape)feature.GetShape()).GetDifference(areaBaseShape); BaseShape differenceResultShape = SqlTypesGeometryHelper.GetDifference((AreaBaseShape)feature.GetShape(), areaBaseShape); MultipolygonShape clippedShape = ConvertSqlQueryResultToMultiPolygonShape(differenceResultShape); if (clippedShape != null && clippedShape.Polygons.Count > 0) { results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } } catch (Exception ex) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); HandleExceptionFromInvalidFeature(feature.Id, ex.Message); } } } else { throw new NotSupportedException("The ShapeFileType is not supported."); } return(results); } }