private IEnumerable <Feature> StandardClip(FeatureSource featureSource, IEnumerable <Feature> features) { lock (featureSource) { Collection <Feature> results = new Collection <Feature>(); //There is a bug about projection boundingbox, here is a workaround for it. bool isOpen = false; Projection tmpProjection = null; if (featureSource.Projection != null && featureSource.Projection is GISEditorManagedProj4Projection && ((GISEditorManagedProj4Projection)featureSource.Projection).IsProjectionParametersEqual) { tmpProjection = featureSource.Projection; if (featureSource.IsOpen) { featureSource.Close(); featureSource.Projection.Close(); isOpen = true; } featureSource.Projection = null; } if (!featureSource.IsOpen) { featureSource.Open(); } Collection <Feature> sourceFeatures = featureSource.GetFeaturesInsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(features), ReturningColumnsType.AllColumns); if (tmpProjection != null) { featureSource.Projection = tmpProjection; if (isOpen) { featureSource.Open(); } } ShapeFileType shapeFileType = ((ShapeFileFeatureSource)featureSource).GetShapeFileType(); if (featureSource.IsOpen) { featureSource.Close(); } int index = 1; int count = sourceFeatures.Count; if (shapeFileType == ShapeFileType.Point || shapeFileType == ShapeFileType.Multipoint) { return(StandardClipPoints(sourceFeatures, features, shapeFileType)); } else if (shapeFileType == ShapeFileType.Polyline) { MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(features)); foreach (var feature in sourceFeatures) { ReportProgress(index * 100 / count); index++; try { if (areaBaseShape.Contains(feature)) { results.Add(feature); } else { var clippedShape = ((LineBaseShape)feature.GetShape()).GetIntersection(areaBaseShape); if (clippedShape != null && clippedShape.Lines.Count > 0) { results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } } catch (Exception ex) { HandleExceptionFromInvalidFeature(feature.Id, ex.Message); } } } else if (shapeFileType == ShapeFileType.Polygon) { MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(features)); foreach (var feature in sourceFeatures) { ReportProgress(index * 100 / count); try { index++; if (areaBaseShape.Contains(feature)) { results.Add(feature); } else { var clippedShape = areaBaseShape.GetIntersection(feature); if (clippedShape != null && clippedShape.Polygons.Count > 0) { results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } } catch (Exception ex) { HandleExceptionFromInvalidFeature(feature.Id, ex.Message); } } } else { throw new NotSupportedException("The ShapeFileType is not supported."); } return(results); } }
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); } }
private IEnumerable <Feature> InverseClip(FeatureSource featureSource, IEnumerable <Feature> clippingFeatures) { lock (featureSource) { if (!featureSource.IsOpen) { featureSource.Open(); } Collection <Feature> results = featureSource.GetFeaturesOutsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(clippingFeatures), ReturningColumnsType.AllColumns); Collection <Feature> sourceFeatures = new Collection <Feature>(); ShapeFileType shapeFileType = ((ShapeFileFeatureSource)featureSource).GetShapeFileType(); int index = 1; if (shapeFileType == ShapeFileType.Point || shapeFileType == ShapeFileType.Multipoint) { featureSource.Open(); Collection <Feature> allFeatures = featureSource.GetAllFeatures(ReturningColumnsType.AllColumns); featureSource.Close(); foreach (Feature f in results) { allFeatures.Remove(f); } foreach (var f in InverseClipPoints(allFeatures, clippingFeatures, shapeFileType)) { results.Add(f); } } else if (shapeFileType == ShapeFileType.Polyline) { bool isOpen = false; Projection tmpProjection = null; MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures)); if (featureSource.Projection != null && featureSource.Projection is GISEditorManagedProj4Projection && ((GISEditorManagedProj4Projection)featureSource.Projection).IsProjectionParametersEqual) { tmpProjection = featureSource.Projection; if (featureSource.IsOpen) { featureSource.Close(); featureSource.Projection.Close(); isOpen = true; } featureSource.Projection = null; } featureSource.Open(); featureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), ReturningColumnsType.AllColumns).ForEach(f => { if (!areaBaseShape.Contains(f)) { sourceFeatures.Add(f); } }); int count = sourceFeatures.Count; if (tmpProjection != null) { featureSource.Projection = tmpProjection; if (isOpen) { featureSource.Open(); } } if (featureSource.IsOpen) { featureSource.Close(); } foreach (var feature in sourceFeatures) { ReportProgress(index * 100 / count); index++; try { if (areaBaseShape.IsDisjointed(feature)) { results.Add(feature); } else { MultilineShape multiLine = (MultilineShape)feature.GetShape(); MultilineShape resultShape = new MultilineShape(); foreach (LineShape lineShape in multiLine.Lines) { if (areaBaseShape.IsDisjointed(lineShape)) { resultShape.Lines.Add(lineShape); } else { Collection <PointShape> points = new Collection <PointShape>(); points.Add(new PointShape(lineShape.Vertices[0])); lineShape.GetIntersection(areaBaseShape).Lines.ForEach(l => { PointShape p1 = new PointShape(l.Vertices[0]); if (points.Count(p => p.X == p1.X && p.Y == p1.Y && p.Z == p1.Z) <= 0) { points.Add(p1); } PointShape p2 = new PointShape(l.Vertices[l.Vertices.Count - 1]); if (points.Count(p => p.X == p2.X && p.Y == p2.Y && p.Z == p2.Z) <= 0) { points.Add(p2); } }); PointShape endPoint = new PointShape(lineShape.Vertices[lineShape.Vertices.Count - 1]); if (points.Count(p => p.X == endPoint.X && p.Y == endPoint.Y && p.Z == endPoint.Z) <= 0) { points.Add(endPoint); } for (int i = 0; i < points.Count; i++) { if (i != points.Count - 1) { LineBaseShape lineBaseShape = lineShape.GetLineOnALine(points[i], points[i + 1]); if (!areaBaseShape.Intersects(lineBaseShape.GetCenterPoint())) { resultShape.Lines.Add((LineShape)lineBaseShape); } } } } } if (resultShape != null && resultShape.Lines.Count > 0) { results.Add(new Feature(resultShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } } catch (Exception ex) { HandleExceptionFromInvalidFeature(feature.Id, ex.Message); } } } else if (shapeFileType == ShapeFileType.Polygon) { MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(clippingFeatures)); bool isOpen = false; Projection tmpProjection = null; if (featureSource.Projection != null && featureSource.Projection is GISEditorManagedProj4Projection && ((GISEditorManagedProj4Projection)featureSource.Projection).IsProjectionParametersEqual) { tmpProjection = featureSource.Projection; if (featureSource.IsOpen) { featureSource.Close(); featureSource.Projection.Close(); isOpen = true; } featureSource.Projection = null; } if (!featureSource.IsOpen) { featureSource.Open(); } featureSource.GetFeaturesInsideBoundingBox(areaBaseShape.GetBoundingBox(), ReturningColumnsType.AllColumns).ForEach(f => { if (!areaBaseShape.IsDisjointed(f)) { sourceFeatures.Add(f); } }); if (featureSource.IsOpen) { featureSource.Close(); } if (tmpProjection != null) { featureSource.Projection = tmpProjection; if (isOpen) { featureSource.Open(); } } int count = sourceFeatures.Count; foreach (var feature in sourceFeatures) { ReportProgress(index * 100 / count); index++; try { if (areaBaseShape.IsDisjointed(feature)) { results.Add(feature); } else { var clippedShape = ((AreaBaseShape)feature.GetShape()).GetDifference(areaBaseShape); if (clippedShape != null && clippedShape.Polygons.Count > 0) { results.Add(new Feature(clippedShape.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } } catch (Exception ex) { HandleExceptionFromInvalidFeature(feature.Id, ex.Message); } } } else { throw new NotSupportedException("The ShapeFileType is not supported."); } return(results); } }