XAML-Map-Control/MapControl/MapPolyline.cs

218 lines
8 KiB
C#
Raw Normal View History

2012-05-04 12:52:20 +02:00
// WPF MapControl - http://wpfmapcontrol.codeplex.com/
// Copyright © 2012 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using System.Linq;
2012-04-25 22:02:53 +02:00
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace MapControl
{
2012-05-04 12:52:20 +02:00
/// <summary>
/// An open map polygon, defined by a collection of geographic locations in the Locations property.
/// </summary>
public class MapPolyline : MapElement
2012-04-25 22:02:53 +02:00
{
public static readonly DependencyProperty StrokeProperty = Shape.StrokeProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata(Brushes.Black, (o, e) => ((MapPolyline)o).drawing.Pen.Brush = (Brush)e.NewValue));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeDashArrayProperty = Shape.StrokeDashArrayProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.DashStyle = new DashStyle((DoubleCollection)e.NewValue, ((MapPolyline)o).StrokeDashOffset)));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeDashOffsetProperty = Shape.StrokeDashOffsetProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.DashStyle = new DashStyle(((MapPolyline)o).StrokeDashArray, (double)e.NewValue)));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeDashCapProperty = Shape.StrokeDashCapProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.DashCap = (PenLineCap)e.NewValue));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeStartLineCapProperty = Shape.StrokeStartLineCapProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.StartLineCap = (PenLineCap)e.NewValue));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeEndLineCapProperty = Shape.StrokeEndLineCapProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.EndLineCap = (PenLineCap)e.NewValue));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeLineJoinProperty = Shape.StrokeLineJoinProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.LineJoin = (PenLineJoin)e.NewValue));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeMiterLimitProperty = Shape.StrokeMiterLimitProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).drawing.Pen.MiterLimit = (double)e.NewValue));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty StrokeThicknessProperty = Shape.StrokeThicknessProperty.AddOwner(
2012-05-04 12:52:20 +02:00
typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).UpdatePenThickness()));
2012-04-25 22:02:53 +02:00
public static readonly DependencyProperty TransformStrokeProperty = DependencyProperty.Register(
2012-05-04 12:52:20 +02:00
"TransformStroke", typeof(bool), typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).UpdatePenThickness()));
public static readonly DependencyProperty LocationsProperty = DependencyProperty.Register(
"Locations", typeof(LocationCollection), typeof(MapPolyline), new FrameworkPropertyMetadata((o, e) => ((MapPolyline)o).UpdateGeometry()));
2012-04-25 22:02:53 +02:00
2012-05-04 12:52:20 +02:00
protected readonly DrawingVisual visual = new DrawingVisual();
protected readonly GeometryDrawing drawing = new GeometryDrawing();
2012-04-25 22:02:53 +02:00
2012-05-04 12:52:20 +02:00
public MapPolyline()
2012-04-25 22:02:53 +02:00
{
drawing.Pen = new Pen(Stroke, StrokeThickness);
using (DrawingContext drawingContext = visual.RenderOpen())
{
drawingContext.DrawDrawing(drawing);
}
Loaded += (o, e) => UpdateGeometry();
}
public Brush Stroke
{
get { return (Brush)GetValue(StrokeProperty); }
set { SetValue(StrokeProperty, value); }
}
public DoubleCollection StrokeDashArray
{
get { return (DoubleCollection)GetValue(StrokeDashArrayProperty); }
set { SetValue(StrokeDashArrayProperty, value); }
}
public double StrokeDashOffset
{
get { return (double)GetValue(StrokeDashOffsetProperty); }
set { SetValue(StrokeDashOffsetProperty, value); }
}
public PenLineCap StrokeDashCap
{
get { return (PenLineCap)GetValue(StrokeDashCapProperty); }
set { SetValue(StrokeDashCapProperty, value); }
}
public PenLineCap StrokeStartLineCap
{
get { return (PenLineCap)GetValue(StrokeStartLineCapProperty); }
set { SetValue(StrokeStartLineCapProperty, value); }
}
public PenLineCap StrokeEndLineCap
{
get { return (PenLineCap)GetValue(StrokeEndLineCapProperty); }
set { SetValue(StrokeEndLineCapProperty, value); }
}
public PenLineJoin StrokeLineJoin
{
get { return (PenLineJoin)GetValue(StrokeLineJoinProperty); }
set { SetValue(StrokeLineJoinProperty, value); }
}
public double StrokeMiterLimit
{
get { return (double)GetValue(StrokeMiterLimitProperty); }
set { SetValue(StrokeMiterLimitProperty, value); }
}
public double StrokeThickness
{
get { return (double)GetValue(StrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
public bool TransformStroke
{
get { return (bool)GetValue(TransformStrokeProperty); }
set { SetValue(TransformStrokeProperty, value); }
}
2012-05-04 12:52:20 +02:00
public LocationCollection Locations
{
get { return (LocationCollection)GetValue(LocationsProperty); }
set { SetValue(LocationsProperty, value); }
}
2012-04-25 22:02:53 +02:00
public double TransformedStrokeThickness
{
get { return drawing.Pen.Thickness; }
}
public PathGeometry TransformedGeometry
{
get { return drawing.Geometry as PathGeometry; }
}
protected override int VisualChildrenCount
{
get { return 1; }
}
protected override Visual GetVisualChild(int index)
{
return visual;
}
protected override void OnInitialized(EventArgs eventArgs)
{
base.OnInitialized(eventArgs);
AddVisualChild(visual);
}
2012-08-08 20:42:06 +02:00
protected override void OnViewportChanged()
2012-04-25 22:02:53 +02:00
{
double scale = 1d;
2012-05-04 12:52:20 +02:00
if (TransformStroke)
2012-04-25 22:02:53 +02:00
{
2012-08-08 20:42:06 +02:00
scale = ParentMap.CenterScale * Map.MeterPerDegree;
2012-04-25 22:02:53 +02:00
}
drawing.Pen.Thickness = scale * StrokeThickness;
}
2012-05-04 12:52:20 +02:00
protected virtual void UpdateGeometry()
{
UpdateGeometry(false);
}
protected void UpdateGeometry(bool closed)
2012-04-25 22:02:53 +02:00
{
2012-08-08 20:42:06 +02:00
if (ParentMap != null && Locations != null && Locations.Count > 0)
2012-04-25 22:02:53 +02:00
{
2012-08-08 20:42:06 +02:00
drawing.Geometry = CreateGeometry(Locations, closed);
OnViewportChanged();
2012-04-25 22:02:53 +02:00
}
else
{
drawing.Geometry = null;
}
}
private void UpdatePenThickness()
{
2012-08-08 20:42:06 +02:00
if (ParentMap != null)
2012-04-25 22:02:53 +02:00
{
2012-08-08 20:42:06 +02:00
OnViewportChanged();
2012-04-25 22:02:53 +02:00
}
}
2012-05-04 12:52:20 +02:00
2012-08-08 20:42:06 +02:00
private Geometry CreateGeometry(LocationCollection locations, bool closed)
2012-05-04 12:52:20 +02:00
{
StreamGeometry geometry = new StreamGeometry
{
2012-08-08 20:42:06 +02:00
Transform = ParentMap.ViewportTransform
2012-05-04 12:52:20 +02:00
};
using (StreamGeometryContext sgc = geometry.Open())
{
2012-08-08 20:42:06 +02:00
sgc.BeginFigure(ParentMap.MapTransform.Transform(locations.First()), closed, closed);
2012-05-04 12:52:20 +02:00
if (Locations.Count > 1)
{
2012-08-08 20:42:06 +02:00
sgc.PolyLineTo(ParentMap.MapTransform.Transform(locations.Skip(1)), true, true);
2012-05-04 12:52:20 +02:00
}
}
return geometry;
}
2012-04-25 22:02:53 +02:00
}
}