using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Linq; using System.Windows; using System.Windows.Controls; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WpfDesktopEdition; namespace CSHowDoISamples { /// /// Interaction logic for DisplayASimpleMap.xaml /// public partial class DisplayASimpleMap : UserControl { public DisplayASimpleMap() { InitializeComponent(); } private void WpfMap_Loaded(object sender, RoutedEventArgs e) { Map1.MapUnit = GeographyUnit.DecimalDegree; Map1.CurrentExtent = new RectangleShape(-155.733, 95.60, 104.42, -81.9); WorldMapKitWmsWpfOverlay worldOverlay = new WorldMapKitWmsWpfOverlay(); Map1.Overlays.Add("WMK", worldOverlay); CurvedLinePointStyle pointStyle = new CurvedLinePointStyle(); pointStyle.Pen = new GeoPen(new GeoSolidBrush(GeoColor.SimpleColors.Red), 3); pointStyle.SkippedFlagColumnName = "IsSkipped"; pointStyle.RequiredColumnNames.Add("IsSkipped"); InMemoryFeatureLayer featureLayer = new InMemoryFeatureLayer(); featureLayer.Open(); featureLayer.Columns.Add(new FeatureSourceColumn("IsSkipped")); featureLayer.Close(); featureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(pointStyle); featureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(PointStyles.Capital2); featureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; int i = -180; Random r = new Random(); while (i <= 180) { Feature feature = new Feature(i, r.Next(-90, 90)); // Set this column value to skip. if (i % 30 == 0) feature.ColumnValues.Add("IsSkipped", "True"); featureLayer.InternalFeatures.Add(feature); i += 20; } LayerOverlay staticOverlay = new LayerOverlay(); staticOverlay.TileType = TileType.SingleTile; staticOverlay.Layers.Add("WorldLayer", featureLayer); Map1.Overlays.Add(staticOverlay); Map1.Refresh(); } } public class CurvedLinePointStyle : PointStyle { public string SkippedFlagColumnName { get; set; } public GeoPen Pen { get; set; } protected override void DrawCore(IEnumerable features, GeoCanvas canvas, Collection labelsInThisLayer, Collection labelsInAllLayers) { double resolution = Math.Max(canvas.CurrentWorldExtent.Width / canvas.Width, canvas.CurrentWorldExtent.Height / canvas.Height); Collection screenPointsCollection = new Collection(); foreach (Feature feature in features) { WellKnownType wktype = feature.GetWellKnownType(); if (wktype == WellKnownType.Point) { screenPointsCollection.Add(ConvertToScreenPoint((PointShape)feature.GetShape(), resolution, canvas.CurrentWorldExtent)); } // TODO: Add multiple points support. } if (canvas is GdiPlusGeoCanvas) { Collection skippedFeatureIndexes = new Collection(); int index = 0; foreach (var feature in features) { if (feature.ColumnValues.ContainsKey(SkippedFlagColumnName)) { bool skipped = false; if (Boolean.TryParse(feature.ColumnValues[SkippedFlagColumnName], out skipped)) { if (skipped) skippedFeatureIndexes.Add(index); } } index++; } Collection> pointsWaitingToDrawLine = new Collection>(); Collection> pointsWaitingToDrawCurvedLine = new Collection>(); for (int i = 0; i < screenPointsCollection.Count; i++) { if (i == 0) { if (skippedFeatureIndexes.Contains(i)) { pointsWaitingToDrawCurvedLine.Add(new Collection()); pointsWaitingToDrawCurvedLine.Last().Add(screenPointsCollection[i]); } else { pointsWaitingToDrawLine.Add(new Collection()); pointsWaitingToDrawLine.Last().Add(screenPointsCollection[i]); } } else { if (skippedFeatureIndexes.Contains(i) && !skippedFeatureIndexes.Contains(i - 1)) { pointsWaitingToDrawCurvedLine.Add(new Collection()); pointsWaitingToDrawCurvedLine.Last().Add(screenPointsCollection[i - 1]); pointsWaitingToDrawCurvedLine.Last().Add(screenPointsCollection[i]); } else if (skippedFeatureIndexes.Contains(i)) { pointsWaitingToDrawCurvedLine.Last().Add(screenPointsCollection[i]); } else if (!skippedFeatureIndexes.Contains(i) && skippedFeatureIndexes.Contains(i - 1)) { pointsWaitingToDrawCurvedLine.Last().Add(screenPointsCollection[i]); pointsWaitingToDrawLine.Add(new Collection()); pointsWaitingToDrawLine.Last().Add(screenPointsCollection[i]); } else if (!skippedFeatureIndexes.Contains(i)) { pointsWaitingToDrawLine.Last().Add(screenPointsCollection[i]); } } } foreach (var points in pointsWaitingToDrawLine) { if (points.Count > 1) { DrawLine(Pen, canvas, ConvertToScreenPointFs(points)); } } foreach (var points in pointsWaitingToDrawCurvedLine) { if (points.Count > 1) { DrawCurvedLine(Pen, canvas, ConvertToScreenPointFs(points)); } } } } private static Collection ConvertToScreenPointFs(IEnumerable points) { Collection pointfs = new Collection(); foreach (var point in points) { pointfs.Add(new ScreenPointF(point.X, point.Y)); } return pointfs; } private static PointF ConvertToScreenPoint(PointShape worldPoint, double resolution, RectangleShape currentExtent) { float screenX = (float)((worldPoint.X - currentExtent.UpperLeftPoint.X) / resolution); float screenY = (float)((currentExtent.UpperLeftPoint.Y - worldPoint.Y) / resolution); return new PointF(screenX, screenY); } private void DrawLine(GeoPen pen, GeoCanvas geoCanvas, IEnumerable screenPoints) { if (!pen.Color.IsTransparent || !(pen.Brush is GeoSolidBrush)) { geoCanvas.DrawLine(screenPoints, pen, DrawingLevel.LevelTwo, XOffsetInPixel, YOffsetInPixel); } } private void DrawCurvedLine(GeoPen pen, GeoCanvas geoCanvas, IEnumerable screenPoints) { if (!(geoCanvas is GdiPlusGeoCanvas)) return; if (!pen.Color.IsTransparent || !(pen.Brush is GeoSolidBrush)) { Bitmap nativeImage = (Bitmap)geoCanvas.NativeImage; PointF[] pointFs = new PointF[screenPoints.Count()]; for (int i = 0; i < pointFs.Length; i++) { ScreenPointF currentPointF = screenPoints.ElementAt(i); pointFs[i] = new PointF(currentPointF.X, currentPointF.Y); } using (Graphics drawingContext = Graphics.FromImage(nativeImage)) { drawingContext.DrawCurve(ConvertToPen(pen), pointFs); } } } private Pen ConvertToPen(GeoPen pen) { if (pen == null) { return null; } Pen resultPen = new Pen(ConvertToColor(pen.Color)); resultPen.Width = pen.Width; resultPen.Brush = ConvertToSolidBrush((GeoSolidBrush)pen.Brush); resultPen.Color = ConvertToColor(pen.Color); resultPen.MiterLimit = pen.MiterLimit; //TODO: here needs more conversion between Geo* to Gdi* for other properties. if (pen.DashPattern != null && pen.DashPattern.Count > 0) { float[] dashPattern = new float[pen.DashPattern.Count]; for (int i = 0; i < dashPattern.Length; i++) { dashPattern[i] = pen.DashPattern[i]; } resultPen.DashPattern = dashPattern; } return resultPen; } private static Color ConvertToColor(GeoColor color) { return Color.FromArgb(color.AlphaComponent, color.RedComponent, color.GreenComponent, color.BlueComponent); } private static SolidBrush ConvertToSolidBrush(GeoSolidBrush brush) { return new SolidBrush(ConvertToColor(brush.Color)); } } }