Advertisement
Guest User

Untitled

a guest
Mar 25th, 2011
343
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.62 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using System.Windows;
  7. using System.Windows.Media;
  8. using System.Windows.Shapes;
  9. using Microsoft.Maps.MapControl;
  10. using Microsoft.Maps.MapControl.Core;
  11. using Expression = System.Linq.Expressions.Expression;
  12.  
  13. namespace BingMapsSL.MultiShape
  14. {
  15.     public abstract class MultiMapShapeBase : MapShapeBase
  16.     {
  17.         // Fields
  18.         private static readonly DependencyProperty FiguresProperty
  19.             = DependencyProperty.Register("Figures",
  20.                                           typeof (IList<LocationCollection>),
  21.                                           typeof (MultiMapShapeBase),
  22.                                           new PropertyMetadata(new PropertyChangedCallback(Locations_Changed)));
  23.  
  24.         private static readonly Func<MapShapeBase, ProjectionUpdateLevel> _pendingUpdateGetAccessor
  25.             = CreatePendingUpdateGetAccessor();
  26.  
  27.         private static readonly Action<MapShapeBase, ProjectionUpdateLevel> _pendingUpdateSetAccessor
  28.             = CreatePendingUpdateSetAccessor();
  29.  
  30.  
  31.         private Point topLeftViewportPoint;
  32.  
  33.         // Methods
  34.         protected MultiMapShapeBase(Shape shape)
  35.             : base(shape)
  36.         {
  37.         }
  38.  
  39.  
  40.         public IList<LocationCollection> Figures
  41.         {
  42.             get { return (IList<LocationCollection>) base.GetValue(FiguresProperty); }
  43.             set { base.SetValue(FiguresProperty, value); }
  44.         }
  45.  
  46.  
  47.         public abstract IList<PointCollection> ProjectedFigures { get; set; }
  48.  
  49.         protected override PointCollection ProjectedPoints
  50.         {
  51.             get { throw new InvalidOperationException("Use ProjectedFigures instead"); }
  52.             set { throw new InvalidOperationException("Use ProjectedFigures instead"); }
  53.         }
  54.  
  55.         private static Func<MapShapeBase, ProjectionUpdateLevel> CreatePendingUpdateGetAccessor()
  56.         {
  57.             ParameterExpression pex = Expression.Parameter(typeof (MapShapeBase));
  58.             FieldInfo fieldInfo = typeof (MapShapeBase).GetField("pendingUpdate",
  59.                                                                  BindingFlags.GetField | BindingFlags.NonPublic |
  60.                                                                  BindingFlags.Instance);
  61.             return
  62.                 Expression.Lambda<Func<MapShapeBase, ProjectionUpdateLevel>>(
  63.                     Expression.MakeMemberAccess(pex, fieldInfo), pex).Compile();
  64.         }
  65.  
  66.         private static Action<MapShapeBase, ProjectionUpdateLevel> CreatePendingUpdateSetAccessor()
  67.         {
  68.             ParameterExpression pex = Expression.Parameter(typeof (MapShapeBase));
  69.             ParameterExpression vex = Expression.Parameter(typeof (ProjectionUpdateLevel));
  70.  
  71.             FieldInfo fieldInfo = typeof (MapShapeBase).GetField("pendingUpdate",
  72.                                                                  BindingFlags.SetField | BindingFlags.NonPublic |
  73.                                                                  BindingFlags.Instance);
  74.  
  75.             return Expression.Lambda<Action<MapShapeBase, ProjectionUpdateLevel>>(
  76.                 Expression.Assign(Expression.MakeMemberAccess(pex, fieldInfo), vex), pex, vex).Compile();
  77.         }
  78.  
  79.         protected override Size ArrangeOverride(Size finalSize)
  80.         {
  81.             base.Content.Arrange(new Rect(topLeftViewportPoint.X, topLeftViewportPoint.Y,
  82.                                           base.Content.DesiredSize.Width + 1.0, base.Content.DesiredSize.Height + 1.0));
  83.             return ParentMap.ViewportSize;
  84.         }
  85.  
  86.         private static void Locations_Changed(DependencyObject o, DependencyPropertyChangedEventArgs ea)
  87.         {
  88.             var base2 = o as MultiMapShapeBase;
  89.             if (base2 != null)
  90.             {
  91.                 var oldValue = ea.OldValue as List<LocationCollection>;
  92.                 if (oldValue != null)
  93.                 {
  94.                     foreach (LocationCollection lc in oldValue)
  95.                     {
  96.                         lc.CollectionChanged -= base2.Locations_CollectionChanged;
  97.                     }
  98.                 }
  99.                 var newValue = ea.NewValue as List<LocationCollection>;
  100.                 if (newValue != null)
  101.                 {
  102.                     foreach (LocationCollection lc in newValue)
  103.                     {
  104.                         lc.CollectionChanged += base2.Locations_CollectionChanged;
  105.                     }
  106.                 }
  107.                 base2.ProjectionUpdated(ProjectionUpdateLevel.Full);
  108.             }
  109.         }
  110.  
  111.         private void Locations_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  112.         {
  113.             ProjectionUpdated(ProjectionUpdateLevel.Full);
  114.         }
  115.  
  116.         protected override Size MeasureOverride(Size availableSize)
  117.         {
  118.             ProjectionUpdateLevel pendingUpdate = _pendingUpdateGetAccessor(this);
  119.             MapBase parentMap = ParentMap;
  120.             if (pendingUpdate != ProjectionUpdateLevel.None)
  121.             {
  122.                 if (Figures != null)
  123.                 {
  124.                     Point point3;
  125.                     if ((pendingUpdate == ProjectionUpdateLevel.Full) && (Figures.Count > 0) && (Figures[0].Count > 0))
  126.                     {
  127.                         var pointList = new List<PointCollection>();
  128.                         var projectedPoints = new List<PointCollection>();
  129.  
  130.                         //The smallest point to be used as the offset for all other points
  131.                         var point = new Point(double.MaxValue, double.MaxValue);
  132.  
  133.                         foreach (LocationCollection lc in Figures)
  134.                         {
  135.                             var points = new PointCollection();
  136.  
  137.                             //find the smallest point in the coolect
  138.                             foreach (Point point2 in parentMap.Mode.LocationToViewportPoint(lc))
  139.                             {
  140.                                 point.X = Math.Min(point.X, point2.X);
  141.                                 point.Y = Math.Min(point.Y, point2.Y);
  142.                                 points.Add(point2);
  143.                             }
  144.  
  145.                             pointList.Add(points);
  146.                         }
  147.  
  148.                         for (int j = 0; j < pointList.Count; j++)
  149.                         {
  150.                             for (int i = 0; i < pointList[j].Count; i++)
  151.                             {
  152.                                 Point point4 = pointList[j][i];
  153.                                 pointList[j][i] = new Point(point4.X - point.X, point4.Y - point.Y);
  154.                             }
  155.  
  156.                             projectedPoints.Add(pointList[j]);
  157.                         }
  158.                         ProjectedFigures = projectedPoints;
  159.                     }
  160.                     if (((ProjectedFigures.Count > 0) && (ProjectedFigures[0].Count > 0) && (Figures.Count > 0) &&
  161.                          (Figures[0].Count > 0)) && parentMap.TryLocationToViewportPoint(Figures[0][0], out point3))
  162.                     {
  163.                         Point point5 = ProjectedFigures[0][0];
  164.                         topLeftViewportPoint = new Point(point3.X - point5.X, point3.Y - point5.Y);
  165.                     }
  166.                 }
  167.                 else
  168.                 {
  169.                     ProjectedFigures.Clear();
  170.                 }
  171.                 _pendingUpdateSetAccessor(this, ProjectionUpdateLevel.None);
  172.             }
  173.             base.Content.Measure(new Size(double.MaxValue, double.MaxValue));
  174.             return parentMap.ViewportSize;
  175.         }
  176.     }
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement