1: public class MapHelper
2: {
3:
4: /// <summary>
5: /// Calculates best map view for an array of points. Similar to VEMap.SetMapView method
6: /// </summary>
7: /// <param name="points">Array of Location objects</param>
8: /// <returns></returns>
9: public static BestView CalculateMapView(IList<Location> points, Map objMap)
10: { //Calculate bounding rectangle
11: double maxLat = -90, minLat = 90, maxLon = -180, minLon = 180;
12: //default zoom scales in km/pixel from http://msdn2.microsoft.com/en-us/library/aa940990.aspx
13: double[] defaultScales = {
14: 78.27152,
15: 39.13576,
16: 19.56788,
17: 9.78394,
18: 4.89197,
19: 2.44598,
20: 1.22299,
21: 0.61150,
22: 0.30575,
23: 0.15287,
24: .07644,
25: 0.03822,
26: 0.01911,
27: 0.00955,
28: 0.00478,
29: 0.00239,
30: 0.00119,
31: 0.0006,
32: 0.0003 };
33:
34: //Calculate bounding box for array of locations
35: for (int i = 0; i < points.Count; i++)
36: {
37: if (points
.Latitude > maxLat)
38: maxLat = points
.Latitude;
39:
40: if (points
.Latitude < minLat)
41: minLat = points
.Latitude;
42:
43: if (points
.Longitude > maxLon)
44: maxLon = points
.Longitude;
45:
46: if (points
.Longitude < minLon)
47: minLon = points
.Longitude;
48: }
49:
50: //calculate center coordinate of bounding box
51: double centerLat = (maxLat + minLat) / 2;
52: double centerLong = (maxLon + minLon) / 2;
53:
54: //create a Location object for the center point
55: Microsoft.Maps.MapControl.Location centerPoint = new Microsoft.Maps.MapControl.Location();
56: centerPoint.Latitude = centerLat;
57: centerPoint.Longitude = centerLong;
58:
59: //want to calculate the distance in km along the center latitude between the two longitudes
60: double meanDistanceX = HaversineDistance(centerLat, minLon, centerLat, maxLon);
61:
62: //want to calculate the distance in km along the center longitude between the two latitudes
63: double meanDistanceY = HaversineDistance(maxLat, centerLong, minLat, centerLong) * 2;
64:
65: //calculates the x and y scales
66: var meanScaleValueX = meanDistanceX / objMap.Width;
67: var meanScaleValueY = meanDistanceY / objMap.Height;
68:
69: double meanScale; //gets the largest scale value to work with
70: if (meanScaleValueX > meanScaleValueY)
71: meanScale = meanScaleValueX;
72: else
73: meanScale = meanScaleValueY;
74:
75: //intialize zoom level variable
76: int zoom = 1; //calculate zoom level
77: for (var i = 1; i < 19; i++)
78: {
79: if (meanScale >= defaultScales
)
80: {
81: zoom = i;
82: break;
83: }
84: }
85:
86: //return a BestView object with the center point and zoom level to use
87: return new BestView(centerPoint, zoom);
88: }
89:
90: /// <summary>
91: /// Calculate the distance in kilometers between two coordinates
92: /// </summary>
93: /// <param name="lat1"></param>
94: /// <param name="lon1"></param>
95: /// <param name="lat2"></param>
96: /// <param name="lon2"></param>
97: /// <returns></returns>
98: private static double HaversineDistance(double lat1, double lon1, double lat2, double lon2)
99: {
100: double earthRadius = 6371;
101: double factor = Math.PI / 180;
102: double dLat = (lat2 - lat1) * factor;
103: double dLon = (lon2 - lon1) * factor;
104: double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(lat1 * factor) * Math.Cos(lat2 * factor) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
105: double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); return earthRadius * c;
106: }
107:
108:
109: public static MapPolygon GetPolygonFromPoint(Location startPoint, Location endPoint)
110: {
111: MapPolygon polygon = new MapPolygon();
112: //polygon.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.LightGray);
113: polygon.Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Black);
114: polygon.StrokeDashCap = PenLineCap.Square;
115: polygon.StrokeDashOffset = 5;
116: polygon.StrokeDashArray = new DoubleCollection() { 0, 2.5 };
117: polygon.StrokeThickness = 1;
118: polygon.Opacity = 1;
119: polygon.Locations = new LocationCollection() {
120: new Location(startPoint),
121: new Location(endPoint.Latitude, startPoint.Longitude),
122: new Location(endPoint),
123: new Location(startPoint.Latitude, endPoint.Longitude) };
124:
125: return polygon;
126: }
127:
128: }
129:
130: public struct BestView
131: {
132: public Location center; public int zoom; //Constructor
133:
134: public BestView(Location _center, int _zoom)
135: {
136: center = _center;
137: zoom = _zoom;
138: }
139: }