Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Linq.Expressions;
- using System.Reflection;
- using System.Windows;
- using System.Windows.Media;
- using System.Windows.Shapes;
- using Microsoft.Maps.MapControl;
- using Microsoft.Maps.MapControl.Core;
- using Expression = System.Linq.Expressions.Expression;
- namespace BingMapsSL.MultiShape
- {
- public abstract class MultiMapShapeBase : MapShapeBase
- {
- // Fields
- private static readonly DependencyProperty FiguresProperty
- = DependencyProperty.Register("Figures",
- typeof (IList<LocationCollection>),
- typeof (MultiMapShapeBase),
- new PropertyMetadata(new PropertyChangedCallback(Locations_Changed)));
- private static readonly Func<MapShapeBase, ProjectionUpdateLevel> _pendingUpdateGetAccessor
- = CreatePendingUpdateGetAccessor();
- private static readonly Action<MapShapeBase, ProjectionUpdateLevel> _pendingUpdateSetAccessor
- = CreatePendingUpdateSetAccessor();
- private Point topLeftViewportPoint;
- // Methods
- protected MultiMapShapeBase(Shape shape)
- : base(shape)
- {
- }
- public IList<LocationCollection> Figures
- {
- get { return (IList<LocationCollection>) base.GetValue(FiguresProperty); }
- set { base.SetValue(FiguresProperty, value); }
- }
- public abstract IList<PointCollection> ProjectedFigures { get; set; }
- protected override PointCollection ProjectedPoints
- {
- get { throw new InvalidOperationException("Use ProjectedFigures instead"); }
- set { throw new InvalidOperationException("Use ProjectedFigures instead"); }
- }
- private static Func<MapShapeBase, ProjectionUpdateLevel> CreatePendingUpdateGetAccessor()
- {
- ParameterExpression pex = Expression.Parameter(typeof (MapShapeBase));
- FieldInfo fieldInfo = typeof (MapShapeBase).GetField("pendingUpdate",
- BindingFlags.GetField | BindingFlags.NonPublic |
- BindingFlags.Instance);
- return
- Expression.Lambda<Func<MapShapeBase, ProjectionUpdateLevel>>(
- Expression.MakeMemberAccess(pex, fieldInfo), pex).Compile();
- }
- private static Action<MapShapeBase, ProjectionUpdateLevel> CreatePendingUpdateSetAccessor()
- {
- ParameterExpression pex = Expression.Parameter(typeof (MapShapeBase));
- ParameterExpression vex = Expression.Parameter(typeof (ProjectionUpdateLevel));
- FieldInfo fieldInfo = typeof (MapShapeBase).GetField("pendingUpdate",
- BindingFlags.SetField | BindingFlags.NonPublic |
- BindingFlags.Instance);
- return Expression.Lambda<Action<MapShapeBase, ProjectionUpdateLevel>>(
- Expression.Assign(Expression.MakeMemberAccess(pex, fieldInfo), vex), pex, vex).Compile();
- }
- protected override Size ArrangeOverride(Size finalSize)
- {
- base.Content.Arrange(new Rect(topLeftViewportPoint.X, topLeftViewportPoint.Y,
- base.Content.DesiredSize.Width + 1.0, base.Content.DesiredSize.Height + 1.0));
- return ParentMap.ViewportSize;
- }
- private static void Locations_Changed(DependencyObject o, DependencyPropertyChangedEventArgs ea)
- {
- var base2 = o as MultiMapShapeBase;
- if (base2 != null)
- {
- var oldValue = ea.OldValue as List<LocationCollection>;
- if (oldValue != null)
- {
- foreach (LocationCollection lc in oldValue)
- {
- lc.CollectionChanged -= base2.Locations_CollectionChanged;
- }
- }
- var newValue = ea.NewValue as List<LocationCollection>;
- if (newValue != null)
- {
- foreach (LocationCollection lc in newValue)
- {
- lc.CollectionChanged += base2.Locations_CollectionChanged;
- }
- }
- base2.ProjectionUpdated(ProjectionUpdateLevel.Full);
- }
- }
- private void Locations_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- ProjectionUpdated(ProjectionUpdateLevel.Full);
- }
- protected override Size MeasureOverride(Size availableSize)
- {
- ProjectionUpdateLevel pendingUpdate = _pendingUpdateGetAccessor(this);
- MapBase parentMap = ParentMap;
- if (pendingUpdate != ProjectionUpdateLevel.None)
- {
- if (Figures != null)
- {
- Point point3;
- if ((pendingUpdate == ProjectionUpdateLevel.Full) && (Figures.Count > 0) && (Figures[0].Count > 0))
- {
- var pointList = new List<PointCollection>();
- var projectedPoints = new List<PointCollection>();
- //The smallest point to be used as the offset for all other points
- var point = new Point(double.MaxValue, double.MaxValue);
- foreach (LocationCollection lc in Figures)
- {
- var points = new PointCollection();
- //find the smallest point in the coolect
- foreach (Point point2 in parentMap.Mode.LocationToViewportPoint(lc))
- {
- point.X = Math.Min(point.X, point2.X);
- point.Y = Math.Min(point.Y, point2.Y);
- points.Add(point2);
- }
- pointList.Add(points);
- }
- for (int j = 0; j < pointList.Count; j++)
- {
- for (int i = 0; i < pointList[j].Count; i++)
- {
- Point point4 = pointList[j][i];
- pointList[j][i] = new Point(point4.X - point.X, point4.Y - point.Y);
- }
- projectedPoints.Add(pointList[j]);
- }
- ProjectedFigures = projectedPoints;
- }
- if (((ProjectedFigures.Count > 0) && (ProjectedFigures[0].Count > 0) && (Figures.Count > 0) &&
- (Figures[0].Count > 0)) && parentMap.TryLocationToViewportPoint(Figures[0][0], out point3))
- {
- Point point5 = ProjectedFigures[0][0];
- topLeftViewportPoint = new Point(point3.X - point5.X, point3.Y - point5.Y);
- }
- }
- else
- {
- ProjectedFigures.Clear();
- }
- _pendingUpdateSetAccessor(this, ProjectionUpdateLevel.None);
- }
- base.Content.Measure(new Size(double.MaxValue, double.MaxValue));
- return parentMap.ViewportSize;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement