private void btnSplitLine_Click(object sender, EventArgs e) { LayerOverlay layerOverLay = (LayerOverlay)winformsMap1.Overlays[1]; MapShapeLayer mapShapeLayer = (MapShapeLayer)layerOverLay.Layers[0]; LineShape lineShape = (LineShape)mapShapeLayer.MapShapes["Line1"].Feature.GetShape(); LineShape lineShape2 = (LineShape)mapShapeLayer.MapShapes["Line2"].Feature.GetShape(); //Gets the crossing MultipointShape with the PointShape that will be used to calculate the two split lines. MultipointShape multipointShape = lineShape.GetCrossing(lineShape2); //Uses the GetLineOnLine (Dynamic Segmentation) to get the two split lines from the intersection point. LineShape splitLineShape1 = (LineShape)lineShape.GetLineOnALine(StartingPoint.FirstPoint, multipointShape.Points[0]); LineShape splitLineShape2 = (LineShape)lineShape.GetLineOnALine(StartingPoint.LastPoint, multipointShape.Points[0]); //Displays the two split lines with different colors to distinguish them. MapShape splitMapShape1 = new MapShape(new Feature(splitLineShape1)); splitMapShape1.ZoomLevels.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Orange, 3, true); splitMapShape1.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapShapeLayer.MapShapes.Add("SplitLine1", splitMapShape1); MapShape splitMapShape2 = new MapShape(new Feature(splitLineShape2)); splitMapShape2.ZoomLevels.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.Turquoise, 3, true); splitMapShape2.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapShapeLayer.MapShapes.Add("SplitLine2", splitMapShape2); //Displays the intersection point as a reference. MapShape pointMapShape = new MapShape(new Feature(multipointShape.Points[0])); pointMapShape.ZoomLevels.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Circle, GeoColor.StandardColors.Red, GeoColor.StandardColors.Black, 1, 9); pointMapShape.ZoomLevels.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapShapeLayer.MapShapes.Add("Point", pointMapShape); winformsMap1.Refresh(layerOverLay); btnSplitLine.Enabled = false; }
private void WriteFeaturesIntoQueue(Collection <Feature> features, FeatureSource featureSource) { foreach (Feature feature in features) { Collection <LineShape> processingLineShapes = GeometryHelper.GetLineShapes(feature); // Get the lineshape of the processing feature. foreach (LineShape processingLineShape in processingLineShapes) { // Define a variable to save the points where the adjacent lines intersect with current processing line. Collection <PointShape> crossingPoints = new Collection <PointShape>(); // Get all the lines in current processing shape bounds. Collection <Feature> adjacentFeatures = featureSource.GetFeaturesInsideBoundingBox(processingLineShape.GetBoundingBox(), ReturningColumnsType.NoColumns); // Loop and see if the queried shape is intersected with processing shape. foreach (Feature adjacentFeature in adjacentFeatures) { LineBaseShape adjacentLineShape = adjacentFeature.GetShape() as LineBaseShape; MultipointShape tempCrossingPoints = processingLineShape.GetCrossing(adjacentLineShape); // The queried shape is intersected with processing shape. foreach (PointShape point in tempCrossingPoints.Points) { bool hasAdded = false; foreach (var item in crossingPoints) { if (point.X == item.X && point.Y == item.Y) { hasAdded = true; break; } } if (!hasAdded) { crossingPoints.Add(point); } } } // Order the crossing points following the sequence of line vertex. Collection <FlagedVertex> vertecesOfNewLine = GeometryHelper.AddCrossingPointToLine(processingLineShape, crossingPoints); Collection <Vertex> verteces = new Collection <Vertex>(); Collection <Feature> lineFeatures = new Collection <Feature>(); foreach (var vertex in vertecesOfNewLine) { verteces.Add(vertex.Vertex); if (vertex.Flag) { if (verteces.Count >= 2) { LineShape segment = new LineShape(verteces); lineFeatures.Add(new Feature(segment, feature.ColumnValues)); verteces.RemoveAt(0); } } } if (lineFeatures.Count > 0) { queue.Enqueue(lineFeatures); } } #if DEBUG Console.WriteLine(string.Format("Done {0} in {1}", feature.Id, features.Count)); #endif } }
private static Feature MakeFeatureValidate(Feature feature) { Feature validFeature = feature.MakeValid(); WellKnownType featureType = feature.GetWellKnownType(); WellKnownType validatedType = validFeature.GetWellKnownType(); Feature result = validFeature; if (validatedType != featureType && validatedType == WellKnownType.GeometryCollection) { GeometryCollectionShape geoCollectionShape = validFeature.GetShape() as GeometryCollectionShape; if (geoCollectionShape != null) { BaseShape resultShape = null; switch (featureType) { case WellKnownType.Point: case WellKnownType.Multipoint: Collection <PointShape> points = new Collection <PointShape>(); foreach (var shape in geoCollectionShape.Shapes) { PointShape point = shape as PointShape; if (point != null) { points.Add(point); } } resultShape = new MultipointShape(points); break; case WellKnownType.Line: case WellKnownType.Multiline: Collection <LineShape> lines = new Collection <LineShape>(); foreach (var shape in geoCollectionShape.Shapes) { LineShape line = shape as LineShape; if (line != null) { lines.Add(line); } } resultShape = new MultilineShape(lines); break; case WellKnownType.Polygon: case WellKnownType.Multipolygon: Collection <PolygonShape> polygons = new Collection <PolygonShape>(); foreach (var shape in geoCollectionShape.Shapes) { PolygonShape polygon = shape as PolygonShape; if (polygon != null) { polygons.Add(polygon); } } resultShape = new MultipolygonShape(polygons); break; default: break; } if (resultShape != null) { result = new Feature(resultShape); } } } return(result); }
private IEnumerable <Feature> StandardClipPoints(IEnumerable <Feature> masterFeatures, IEnumerable <Feature> clippingFeatures) { ConcurrentQueue <Feature> results = new ConcurrentQueue <Feature>(); int index = 1; int count = masterFeatures.Count(); ConcurrentQueue <Feature> cqMasterFeatures = new ConcurrentQueue <Feature>(masterFeatures); if (count > 0) { var firstFeature = masterFeatures.FirstOrDefault(); var firstWktType = firstFeature.GetWellKnownType(); if (firstWktType == WellKnownType.Point) { Parallel.ForEach(cqMasterFeatures, feature => { index++; isCanceled = ReportProgress(index, count); if (isCanceled) { return; } if (clippingFeatures.Any(f => { try //{ return f.GetShape().Intersects(feature); } { return(SqlTypesGeometryHelper.Intersects(f.GetShape(), feature)); } catch (Exception ex) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); HandleExceptionFromInvalidFeature(feature.Id, ex.Message); return(false); } })) { results.Enqueue(feature); } }); } else { Parallel.ForEach(cqMasterFeatures, feature => { isCanceled = ReportProgress(index, count); if (isCanceled) { return; } index++; MultipointShape multiPoints = feature.GetShape() as MultipointShape; if (multiPoints != null) { MultipointShape resultPoints = new MultipointShape(); Parallel.ForEach(multiPoints.Points, p => { if (clippingFeatures.Any(f => { try //{ return f.GetShape().Intersects(p); } { return(SqlTypesGeometryHelper.Intersects(f.GetShape(), p)); } catch (Exception ex) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); HandleExceptionFromInvalidFeature(feature.Id, ex.Message); return(false); } })) { resultPoints.Points.Add(p); } }); if (resultPoints.Points.Count > 0) { results.Enqueue(new Feature(resultPoints.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } }); } } return(results); }
private IEnumerable <Feature> StandardClipPoints(IEnumerable <Feature> masterFeatures, IEnumerable <Feature> clippingFeatures, ShapeFileType shpFileType) { ConcurrentQueue <Feature> results = new ConcurrentQueue <Feature>(); int index = 1; int count = masterFeatures.Count(); ConcurrentQueue <Feature> cqMasterFeatures = new ConcurrentQueue <Feature>(masterFeatures); if (shpFileType == ShapeFileType.Point) { Parallel.ForEach(cqMasterFeatures, feature => { index++; ReportProgress(index * 100 / count); if (clippingFeatures.Any(f => { try { return(f.GetShape().Intersects(feature)); } catch (Exception ex) { HandleExceptionFromInvalidFeature(feature.Id, ex.Message); return(false); } })) { results.Enqueue(feature); } }); } else { Parallel.ForEach(cqMasterFeatures, feature => { ReportProgress(index * 100 / count); index++; MultipointShape multiPoints = feature.GetShape() as MultipointShape; if (multiPoints != null) { MultipointShape resultPoints = new MultipointShape(); Parallel.ForEach(multiPoints.Points, p => { if (clippingFeatures.Any(f => { try { return(f.GetShape().Intersects(p)); } catch (Exception ex) { HandleExceptionFromInvalidFeature(feature.Id, ex.Message); return(false); } })) { resultPoints.Points.Add(p); } }); if (resultPoints.Points.Count > 0) { results.Enqueue(new Feature(resultPoints.GetWellKnownBinary(), feature.Id, feature.ColumnValues)); } } }); } return(results); }
private static TileFeature GetVectorTileFeature(Feature feature, int zoom, int tileSize, RectangleInt tileScreenBoundingBox, int simplificationFactor, RectangleShape tileBoundingBox) { TileFeature tileFeature = new TileFeature(); switch (feature.GetWellKnownType()) { case WellKnownType.Line: case WellKnownType.Multiline: tileFeature.Type = GeometryType.LineString; MultilineShape multiLineShape = new MultilineShape(feature.GetWellKnownBinary()); ProcessLineShape(zoom, tileSize, tileScreenBoundingBox, tileFeature, multiLineShape, simplificationFactor, tileBoundingBox); break; case WellKnownType.Polygon: case WellKnownType.Multipolygon: tileFeature.Type = GeometryType.Polygon; MultipolygonShape multiPolygonShape = new MultipolygonShape(feature.GetWellKnownBinary()); foreach (PolygonShape polygonShape in multiPolygonShape.Polygons) { ProcessRingShape(zoom, tileSize, tileScreenBoundingBox, tileFeature, polygonShape.OuterRing, simplificationFactor, tileBoundingBox); foreach (RingShape ringShape in polygonShape.InnerRings) { ProcessRingShape(zoom, tileSize, tileScreenBoundingBox, tileFeature, ringShape, simplificationFactor, tileBoundingBox); } } break; case WellKnownType.Point: case WellKnownType.Multipoint: tileFeature.Type = GeometryType.Point; List <PointInt> coordinates = new List <PointInt>(); MultipointShape multiPointShape = new MultipointShape(); if (feature.GetWellKnownType() == WellKnownType.Point) { PointShape pointShape = new PointShape(feature.GetWellKnownBinary()); multiPointShape.Points.Add(pointShape); } else if (feature.GetWellKnownType() == WellKnownType.Multipoint) { multiPointShape = new MultipointShape(feature.GetWellKnownBinary()); } foreach (PointShape point in multiPointShape.Points) { PointInt pointI = WorldPointToTilePoint(point.X, point.Y, zoom, tileSize, tileBoundingBox); coordinates.Add(new PointInt(pointI.X, pointI.Y)); } if (coordinates.Count > 0) { tileFeature.Geometry.Add(coordinates); } break; default: tileFeature.Type = GeometryType.Unknown; break; } //add the record attributes foreach (var attributes in feature.ColumnValues) { tileFeature.Attributes.Add(new TileAttribute(attributes.Key, attributes.Value)); } return(tileFeature); }
// Tuple // item1: columnName, // item2: columnType, // item3: OperatorMode. public static Collection <Feature> Dissolve(IEnumerable <string> dissolveColumnNames , IEnumerable <Tuple <string, string, DissolveOperatorMode> > pairedColumnStrategies , IEnumerable <Feature> featuresToDissovle) { var featureGroupByShapeType = featuresToDissovle.GroupBy(f => { return(f.GetShape().GetType()); }); Collection <Feature> dissolveFeatures = new Collection <Feature>(); Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > dissolveAction = new Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > ((groupByType, finalProcessAction) => { var groupByColumns = GroupByColumns(groupByType, dissolveColumnNames); groupByColumns.ForEach(groupFeature => { Dictionary <string, string> newColumnValues = new Dictionary <string, string>(); foreach (var tmpMatchColumn in dissolveColumnNames) { newColumnValues.Add(tmpMatchColumn, groupFeature.First().ColumnValues[tmpMatchColumn]); } foreach (var operatorPair in pairedColumnStrategies) { CollectNewColumnValues(groupFeature, newColumnValues, operatorPair); } newColumnValues.Add("Count", groupFeature.Count().ToString()); try { if (finalProcessAction != null) { finalProcessAction(groupFeature, newColumnValues); } } catch (Exception ex) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); } }); }); featureGroupByShapeType.ForEach(groupByType => { if (groupByType.Key.IsSubclassOf(typeof(AreaBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { MultipolygonShape dissolveShape = AreaBaseShape.Union(GetValidFeatures(tmpFeatures)); if (dissolveShape != null) { Feature dissolveFeature = new Feature(dissolveShape, tmpColumnValues); dissolveFeatures.Add(dissolveFeature); } }); } else if (groupByType.Key.IsSubclassOf(typeof(LineBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { //MultilineShape dissolveShape = LineBaseShape.Union(tmpFeatures); //Feature dissolveFeature = new Feature(dissolveShape, tmpColumnValues); //dissolveFeatures.Add(dissolveFeature); MultilineShape dissolveShape = new MultilineShape(); tmpFeatures.ForEach(tmpFeature => { BaseShape tmpShape = tmpFeature.GetShape(); LineShape tmpLine = tmpShape as LineShape; MultilineShape tmpMLine = tmpShape as MultilineShape; if (tmpLine != null) { dissolveShape.Lines.Add(tmpLine); } else if (tmpMLine != null) { tmpMLine.Lines.ForEach(tmpLineInMLine => dissolveShape.Lines.Add(tmpLineInMLine)); } }); if (dissolveShape.Lines.Count > 0) { dissolveFeatures.Add(new Feature(dissolveShape, tmpColumnValues)); } }); } else if (groupByType.Key.IsSubclassOf(typeof(PointBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { MultipointShape multipointShape = new MultipointShape(); tmpFeatures.ForEach(tmpFeature => { BaseShape tmpShape = tmpFeature.GetShape(); PointShape tmpPoint = tmpShape as PointShape; MultipointShape tmpMPoint = tmpShape as MultipointShape; if (tmpPoint != null) { multipointShape.Points.Add(tmpPoint); } else if (tmpMPoint != null) { tmpMPoint.Points.ForEach(tmpPointInMPointShape => multipointShape.Points.Add(tmpPointInMPointShape)); } }); dissolveFeatures.Add(new Feature(multipointShape, tmpColumnValues)); }); } }); return(dissolveFeatures); }
//private IEnumerable<string> GetMatchColumnsFromString(string matchColumnsInString) //{ // string[] columns = matchColumnsInString.Split(','); // return columns; //} private void Dissolve() { Collection <Feature> dissolvedFeatures = new Collection <Feature>(); // get features to dissolve. Collection <Feature> featuresToDissolve = GetFeaturesToDissolve(); // group features. var featureGroupByShapeType = featuresToDissolve.GroupBy(f => { return(f.GetShape().GetType()); }); // collect export columns. var filteredFeatureColumns = new Collection <FeatureSourceColumn>(); foreach (var matchColumn in this.matchColumns) { var tmpColumn = featureColumns.FirstOrDefault(f => f.ColumnName.Equals(matchColumn, StringComparison.Ordinal)); if (tmpColumn != null) { filteredFeatureColumns.Add(tmpColumn); } } foreach (var extraColumn in this.operatorPairs) { var tmpColumn = featureColumns.FirstOrDefault(f => f.ColumnName.Equals(extraColumn.ColumnName, StringComparison.Ordinal)); if (tmpColumn != null) { filteredFeatureColumns.Add(tmpColumn); } } filteredFeatureColumns.Add(new FeatureSourceColumn("Count", "Integer", 8)); Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > dissolveAction = new Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > ((groupByType, finalProcessAction) => { //CancelTask(this.CancellationSource.Token, content, parameter); var groupByColumns = GroupByColumns(groupByType, this.matchColumns); groupByColumns.ForEach(groupFeature => { //CancelTask(this.CancellationSource.Token, content, parameter); Dictionary <string, string> newColumnValues = new Dictionary <string, string>(); foreach (var tmpMatchColumn in this.matchColumns) { newColumnValues.Add(tmpMatchColumn, groupFeature.First().ColumnValues[tmpMatchColumn]); } foreach (var operatorPair in this.operatorPairs) { //CancelTask(this.CancellationSource.Token, content, parameter); CollectNewColumnValues(groupFeature, newColumnValues, operatorPair); var value = newColumnValues[operatorPair.ColumnName]; var resultColumn = filteredFeatureColumns.FirstOrDefault(c => c.ColumnName.Equals(operatorPair.ColumnName)); if (resultColumn != null) { if (resultColumn.MaxLength < value.Length) { var indexOf = filteredFeatureColumns.IndexOf(resultColumn); filteredFeatureColumns.RemoveAt(indexOf); var newColumn = new FeatureSourceColumn(resultColumn.ColumnName, resultColumn.TypeName, value.Length); filteredFeatureColumns.Insert(indexOf, newColumn); } } } newColumnValues.Add("Count", groupFeature.Count().ToString()); try { if (finalProcessAction != null) { finalProcessAction(groupFeature, newColumnValues); } } catch (Exception e) { GisEditor.LoggerManager.Log(LoggerLevel.Debug, e.Message, new ExceptionInfo(e)); throw e; } }); }); foreach (var groupByType in featureGroupByShapeType) { try { //CancelTask(this.CancellationSource.Token, content, parameter); if (groupByType.Key.IsSubclassOf(typeof(AreaBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { //MultipolygonShape dissolveShape = AreaBaseShape.Union(GetValidFeatures(tmpFeatures)); List <AreaBaseShape> areaShapes = GetValidFeatures(tmpFeatures) .Select(f => f.GetShape()) .OfType <AreaBaseShape>() .ToList(); MultipolygonShape dissolveShape = (MultipolygonShape)SqlTypesGeometryHelper.Union(areaShapes); if (dissolveShape != null) { Feature dissolveFeature = new Feature(dissolveShape, tmpColumnValues); dissolvedFeatures.Add(dissolveFeature); } }); } else if (groupByType.Key.IsSubclassOf(typeof(LineBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { MultilineShape dissolveShape = new MultilineShape(); tmpFeatures.ForEach(tmpFeature => { BaseShape tmpShape = tmpFeature.GetShape(); LineShape tmpLine = tmpShape as LineShape; MultilineShape tmpMLine = tmpShape as MultilineShape; if (tmpLine != null) { dissolveShape.Lines.Add(tmpLine); } else if (tmpMLine != null) { tmpMLine.Lines.ForEach(tmpLineInMLine => dissolveShape.Lines.Add(tmpLineInMLine)); } }); if (dissolveShape.Lines.Count > 0) { dissolvedFeatures.Add(new Feature(dissolveShape, tmpColumnValues)); } }); } else if (groupByType.Key.IsSubclassOf(typeof(PointBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { MultipointShape multipointShape = new MultipointShape(); tmpFeatures.ForEach(tmpFeature => { BaseShape tmpShape = tmpFeature.GetShape(); PointShape tmpPoint = tmpShape as PointShape; MultipointShape tmpMPoint = tmpShape as MultipointShape; if (tmpPoint != null) { multipointShape.Points.Add(tmpPoint); } else if (tmpMPoint != null) { tmpMPoint.Points.ForEach(tmpPointInMPointShape => multipointShape.Points.Add(tmpPointInMPointShape)); } }); dissolvedFeatures.Add(new Feature(multipointShape, tmpColumnValues)); }); } if (isCanceled) { break; } } catch (Exception ex) { var errorEventArgs = new UpdatingTaskProgressEventArgs(TaskState.Error); errorEventArgs.Error = new ExceptionInfo(string.Format(CultureInfo.InvariantCulture, "Feature id: {0}, {1}" , groupByType.FirstOrDefault().Id, ex.Message) , ex.StackTrace , ex.Source); GisEditor.LoggerManager.Log(LoggerLevel.Debug, ex.Message, new ExceptionInfo(ex)); errorEventArgs.Message = groupByType.FirstOrDefault().Id; OnUpdatingProgress(errorEventArgs); continue; } } if (!isCanceled) { string saveFolder = Path.GetDirectoryName(outputPathFileName); if (!Directory.Exists(saveFolder)) { Directory.CreateDirectory(saveFolder); } var info = new FileExportInfo(dissolvedFeatures, filteredFeatureColumns, outputPathFileName, Wkt); Export(info); } }
/// <summary> /// Here in the DrawCore we cluster the features /// </summary> protected override void DrawCore(IEnumerable <Feature> features, GeoCanvas canvas, Collection <SimpleCandidate> labelsInThisLayer, Collection <SimpleCandidate> labelsInAllLayers) { // We get the scale to determine the grid. This scale property should really be on the Canvas! double scale = ExtentHelper.GetScale(canvas.CurrentWorldExtent, canvas.Width, canvas.MapUnit); // Setup our grid for clustering the points. This is where we specify our cell size in pixels MapSuiteTileMatrix mapSuiteTileMatrix = new MapSuiteTileMatrix(scale, cellSize, cellSize, canvas.MapUnit); // Pass in the current extent to get our grid cells. All points in these cells will be consolidated IEnumerable <TileMatrixCell> tileMatricCells = mapSuiteTileMatrix.GetContainedCells(canvas.CurrentWorldExtent); // Create an unused features list, as we add them to clusters we will remove them from here // This is just for speed so we don't re-test lots of already associated features Dictionary <string, string> unusedFeatures = new Dictionary <string, string>(); foreach (Feature feature in features) { if (feature.GetWellKnownType() != WellKnownType.Point && feature.GetWellKnownType() != WellKnownType.Multipoint) { continue; } unusedFeatures.Add(feature.Id, feature.Id); } // Loop through each cell and find the features that fit inside of it foreach (TileMatrixCell cell in tileMatricCells) { int featureCount = 0; MultipointShape tempMultiPointShape = new MultipointShape(); foreach (Feature feature in features) { // Make sure the feature has not been used in another cluster if (unusedFeatures.ContainsKey(feature.Id)) { // Check if the cell contains the feature if (cell.BoundingBox.Contains(feature.GetBoundingBox())) { featureCount++; unusedFeatures.Remove(feature.Id); if (feature.GetWellKnownType() == WellKnownType.Multipoint) { MultipointShape multipointShape = feature.GetShape() as MultipointShape; foreach (var item in multipointShape.Points) { tempMultiPointShape.Points.Add(item); } } else { tempMultiPointShape.Points.Add(feature.GetShape() as PointShape); } } } } if (featureCount > 0) { // Add the feature count to the new feature we created. The feature will be placed // at the center of gravity of all the clustered features of the cell we created. Dictionary <string, string> featureValues = new Dictionary <string, string>(); featureValues.Add("FeatureCount", featureCount.ToString(CultureInfo.InvariantCulture)); bool isMatch = false; for (int i = 0; i < classBreakPoints.Count - 1; i++) { var startItem = classBreakPoints.ElementAt(i); var endItem = classBreakPoints.ElementAt(i + 1); if (featureCount >= startItem.Key && featureCount < endItem.Key) { // Draw the point shape startItem.Value.Draw(new Feature[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers); isMatch = true; break; } } if (!isMatch && featureCount >= classBreakPoints.LastOrDefault().Key) { classBreakPoints.LastOrDefault().Value.Draw(new Feature[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers); } if (featureCount != 1) { // Draw the text style to show how many feaures are consolidated in the cluster textSytle.Draw(new Feature[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers); } } } }
protected override void DrawCore(IEnumerable <Feature> features, GeoCanvas canvas, Collection <SimpleCandidate> labelsInThisLayer, Collection <SimpleCandidate> labelsInAllLayers) { double scale = ExtentHelper.GetScale(canvas.CurrentWorldExtent, canvas.Width, canvas.MapUnit); MapSuiteTileMatrix mapSuiteTileMatrix = new MapSuiteTileMatrix(scale, cellSize, cellSize, canvas.MapUnit); IEnumerable <TileMatrixCell> tileMatricCells = mapSuiteTileMatrix.GetContainedCells(canvas.CurrentWorldExtent); Dictionary <string, string> unusedFeatures = new Dictionary <string, string>(); foreach (Feature feature in features) { if (feature.GetWellKnownType() != WellKnownType.Point && feature.GetWellKnownType() != WellKnownType.Multipoint) { continue; } unusedFeatures.Add(feature.Id, feature.Id); } foreach (TileMatrixCell cell in tileMatricCells) { int featureCount = 0; MultipointShape tempMultiPointShape = new MultipointShape(); foreach (Feature feature in features) { // Make sure the feature has not been used in another cluster if (unusedFeatures.ContainsKey(feature.Id)) { // Check if the cell contains the feature if (cell.BoundingBox.Contains(feature.GetBoundingBox())) { featureCount++; unusedFeatures.Remove(feature.Id); if (feature.GetWellKnownType() == WellKnownType.Multipoint) { MultipointShape multipointShape = feature.GetShape() as MultipointShape; foreach (var item in multipointShape.Points) { tempMultiPointShape.Points.Add(item); } } else { tempMultiPointShape.Points.Add(feature.GetShape() as PointShape); } } } } if (featureCount > 0) { // Add the feature count to the new feature we created. The feature will be placed // at the center of gravity of all the clustered features of the cell we created. Dictionary <string, string> featureValues = new Dictionary <string, string>(); featureValues.Add("FeatureCount", featureCount.ToString(CultureInfo.InvariantCulture)); bool isMatch = false; for (int i = 0; i < classBreakPoint.Count - 1; i++) { var startItem = classBreakPoint.ElementAt(i); var endItem = classBreakPoint.ElementAt(i + 1); if (featureCount >= startItem.Key && featureCount < endItem.Key) { //Draw the point shape startItem.Value.Draw(new[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers); isMatch = true; break; } } if (!isMatch && featureCount >= classBreakPoint.LastOrDefault().Key) { classBreakPoint.LastOrDefault().Value.Draw(new[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers); } if (featureCount != 1) { // Draw the text style to show how many feaures are consolidated in the cluster textSytle.Draw(new[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers); } } } }
private void Dissolve() { try { Collection <Feature> dissolvedFeatures = new Collection <Feature>(); // get features to dissolve. Collection <Feature> featuresToDissolve = GetFeaturesToDissolve(); // group features. var featureGroupByShapeType = featuresToDissolve.GroupBy(f => { return(f.GetShape().GetType()); }); Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > dissolveAction = new Action <IGrouping <Type, Feature>, Action <IEnumerable <Feature>, Dictionary <string, string> > > ((groupByType, finalProcessAction) => { //CancelTask(this.CancellationSource.Token, content, parameter); var groupByColumns = GroupByColumns(groupByType, this.matchColumns); groupByColumns.ForEach(groupFeature => { //CancelTask(this.CancellationSource.Token, content, parameter); Dictionary <string, string> newColumnValues = new Dictionary <string, string>(); foreach (var tmpMatchColumn in this.matchColumns) { newColumnValues.Add(tmpMatchColumn, groupFeature.First().ColumnValues[tmpMatchColumn]); } foreach (var operatorPair in this.operatorPairs) { //CancelTask(this.CancellationSource.Token, content, parameter); CollectNewColumnValues(groupFeature, newColumnValues, operatorPair); } newColumnValues.Add("Count", groupFeature.Count().ToString()); try { if (finalProcessAction != null) { finalProcessAction(groupFeature, newColumnValues); } } catch { } }); }); featureGroupByShapeType.ForEach(groupByType => { //CancelTask(this.CancellationSource.Token, content, parameter); if (groupByType.Key.IsSubclassOf(typeof(AreaBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { MultipolygonShape dissolveShape = AreaBaseShape.Union(GetValidFeatures(tmpFeatures)); if (dissolveShape != null) { Feature dissolveFeature = new Feature(dissolveShape, tmpColumnValues); dissolvedFeatures.Add(dissolveFeature); } }); } else if (groupByType.Key.IsSubclassOf(typeof(LineBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { //MultilineShape dissolveShape = LineBaseShape.Union(tmpFeatures); //Feature dissolveFeature = new Feature(dissolveShape, tmpColumnValues); //dissolveFeatures.Add(dissolveFeature); MultilineShape dissolveShape = new MultilineShape(); tmpFeatures.ForEach(tmpFeature => { BaseShape tmpShape = tmpFeature.GetShape(); LineShape tmpLine = tmpShape as LineShape; MultilineShape tmpMLine = tmpShape as MultilineShape; if (tmpLine != null) { dissolveShape.Lines.Add(tmpLine); } else if (tmpMLine != null) { tmpMLine.Lines.ForEach(tmpLineInMLine => dissolveShape.Lines.Add(tmpLineInMLine)); } }); if (dissolveShape.Lines.Count > 0) { dissolvedFeatures.Add(new Feature(dissolveShape, tmpColumnValues)); } }); } else if (groupByType.Key.IsSubclassOf(typeof(PointBaseShape))) { dissolveAction(groupByType, (tmpFeatures, tmpColumnValues) => { MultipointShape multipointShape = new MultipointShape(); tmpFeatures.ForEach(tmpFeature => { BaseShape tmpShape = tmpFeature.GetShape(); PointShape tmpPoint = tmpShape as PointShape; MultipointShape tmpMPoint = tmpShape as MultipointShape; if (tmpPoint != null) { multipointShape.Points.Add(tmpPoint); } else if (tmpMPoint != null) { tmpMPoint.Points.ForEach(tmpPointInMPointShape => multipointShape.Points.Add(tmpPointInMPointShape)); } }); dissolvedFeatures.Add(new Feature(multipointShape, tmpColumnValues)); }); } }); // collect export columns. var filteredFeatureColumns = new Collection <FeatureSourceColumn>(); foreach (var matchColumn in this.matchColumns) { var tmpColumn = featureColumns.FirstOrDefault(f => f.ColumnName.Equals(matchColumn, StringComparison.Ordinal)); if (tmpColumn != null) { filteredFeatureColumns.Add(tmpColumn); } } foreach (var extraColumn in this.operatorPairs) { var tmpColumn = featureColumns.FirstOrDefault(f => f.ColumnName.Equals(extraColumn.ColumnName, StringComparison.Ordinal)); if (tmpColumn != null) { filteredFeatureColumns.Add(tmpColumn); } } filteredFeatureColumns.Add(new FeatureSourceColumn("Count", "Integer", 8)); string saveFolder = Path.GetDirectoryName(outputPath); if (!Directory.Exists(saveFolder)) { Directory.CreateDirectory(saveFolder); } ShpFileExporter exporter = new ShpFileExporter(); exporter.ExportToFile(new FileExportInfo(dissolvedFeatures, filteredFeatureColumns, outputPath, Wkt)); } catch (Exception e) { } finally { var args = new UpdatingProgressLongRunningTaskPluginEventArgs(LongRunningTaskState.Updating); args.Message = "Finished"; OnUpdatingProgress(args); } }