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));
}
}
}