private int StandardClipLines(IEnumerable <Feature> features, Collection <Feature> results, Collection <Feature> sourceFeatures, int index, int count) { //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(features)); List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(features).Select(f => f.GetShape()).OfType <AreaBaseShape>().ToList(); MultipolygonShape areaBaseShape = (MultipolygonShape)SqlTypesGeometryHelper.Union(clippingAreaShapes); ConcurrentQueue <Feature> concurrentResult = new ConcurrentQueue <Feature>(); Parallel.ForEach(sourceFeatures, feature => { try { //if (areaBaseShape.Contains(feature)) if (SqlTypesGeometryHelper.Contains(areaBaseShape, feature)) { concurrentResult.Enqueue(feature); } else { //var clippedShape = ((LineBaseShape)feature.GetShape()).GetIntersection(areaBaseShape); var clippedShape = SqlTypesGeometryHelper.GetIntersection(feature.GetShape(), areaBaseShape) as MultilineShape; if (clippedShape != null && clippedShape.Lines.Count > 0) { concurrentResult.Enqueue(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); } finally { isCanceled = ReportProgress(index++, count); } }); foreach (var feature in concurrentResult) { results.Add(feature); } return(index); }
private IEnumerable <Feature> StandardClip(FeatureLayer featureLayer, IEnumerable <Feature> features) { lock (featureLayer) { Collection <Feature> results = new Collection <Feature>(); #region replace project to null bool isOpen = false; Proj4ProjectionInfo projectionInfo = featureLayer.GetProj4ProjectionInfo(); if (projectionInfo != null && projectionInfo.CanProject) { if (featureLayer.IsOpen) { featureLayer.Close(); projectionInfo.Close(); isOpen = true; } featureLayer.FeatureSource.Projection = null; } #endregion replace project to null Collection <Feature> tmpFeatures = new Collection <Feature>(); if (projectionInfo != null && projectionInfo.CanProject) { projectionInfo.Open(); foreach (var item in features) { tmpFeatures.Add(projectionInfo.ConvertToInternalProjection(item)); } projectionInfo.Close(); } else { tmpFeatures = new Collection <Feature>(features.ToList()); } if (!featureLayer.IsOpen) { featureLayer.Open(); } List <Feature> tmpSourceFeatures = featureLayer.FeatureSource.GetFeaturesInsideBoundingBox(ExtentHelper.GetBoundingBoxOfItems(tmpFeatures), featureLayer.GetDistinctColumnNames()).Select(f => f.MakeValidIfCan()).ToList(); Collection <Feature> sourceFeatures = new Collection <Feature>(tmpSourceFeatures); if (projectionInfo != null) { featureLayer.FeatureSource.Projection = projectionInfo.Projection; if (isOpen) { featureLayer.Open(); } } SimpleShapeType simpleShapeType = SimpleShapeType.Unknown; var shapeAdapter = GisEditor.LayerManager.GetLayerPlugins(featureLayer.GetType()).FirstOrDefault() as FeatureLayerPlugin; if (shapeAdapter != null) { simpleShapeType = shapeAdapter.GetFeatureSimpleShapeType(featureLayer); } if (featureLayer.IsOpen) { featureLayer.Close(); } int index = 1; int count = sourceFeatures.Count; if (simpleShapeType == SimpleShapeType.Point) { return(StandardClipPoints(sourceFeatures, tmpFeatures)); } else if (simpleShapeType == SimpleShapeType.Line) { StandardClipLines(tmpFeatures, results, sourceFeatures, index, count); } else if (simpleShapeType == SimpleShapeType.Area) { //MultipolygonShape areaBaseShape = AreaBaseShape.Union(GetValidFeatures(tmpFeatures)); List <AreaBaseShape> clippingAreaShapes = GetValidFeatures(tmpFeatures) .Select(f => f.GetShape()) .OfType <AreaBaseShape>() .ToList(); BaseShape unionResultShape = SqlTypesGeometryHelper.Union(clippingAreaShapes); MultipolygonShape areaBaseShape = ConvertSqlQueryResultToMultiPolygonShape(unionResultShape); foreach (var feature in sourceFeatures) { isCanceled = ReportProgress(index, count); if (isCanceled) { break; } try { index++; //if (areaBaseShape.Contains(feature)) if (SqlTypesGeometryHelper.Contains(areaBaseShape, feature)) { results.Add(feature); } else { //var clippedShape = areaBaseShape.GetIntersection(feature); AreaBaseShape targetAreaShape = feature.GetShape() as AreaBaseShape; if (targetAreaShape != null) { var clippedShape = SqlTypesGeometryHelper.GetIntersection(areaBaseShape, targetAreaShape) as MultipolygonShape; 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."); } Collection <Feature> convertedFeatures = new Collection <Feature>(); if (projectionInfo != null && projectionInfo.CanProject) { projectionInfo.Open(); foreach (var item in results) { convertedFeatures.Add(projectionInfo.ConvertToExternalProjection(item)); } projectionInfo.Close(); } else { convertedFeatures = new Collection <Feature>(results.ToList()); } return(convertedFeatures); } }