/Main/src/DynamicDataDisplay.Maps/MapTileProvider.cs
C# | 183 lines | 149 code | 29 blank | 5 comment | 15 complexity | 9cd450606ac90cc52bcf47fe61a6dd14 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Windows; 6using Microsoft.Research.DynamicDataDisplay.Common; 7using System.Diagnostics; 8 9namespace Microsoft.Research.DynamicDataDisplay.Charts.Maps 10{ 11 public class MapTileProvider : TileProvider 12 { 13 public MapTileProvider() 14 { 15 rect = DataRect.FromPoints(minX, minY, maxX, maxY); 16 } 17 18 private double minX = -180; 19 private double maxX = 180; 20 private double minY = -87; 21 private double maxY = 87; 22 private DataRect rect; 23 24 public double MaxLatitude 25 { 26 get { return maxY; } 27 set 28 { 29 maxY = value; 30 minY = -value; 31 32 rect = DataRect.FromPoints(minX, minY, maxX, maxY); 33 } 34 } 35 36 private double maxShaderLatitude = 85; 37 public double MaxShaderLatitude 38 { 39 get { return maxShaderLatitude; } 40 set { maxShaderLatitude = value; } 41 } 42 43 public double MinLatitude 44 { 45 get { return minY; } 46 } 47 48 public double XSize { get { return maxX - minX; } } 49 public double YSize { get { return maxY - minY; } } 50 51 public override DataRect GetTileBounds(TileIndex tile) 52 { 53 if (tile.Level == 0) 54 return rect; 55 56 double width = GetTileWidth(tile.Level); 57 double height = GetTileHeight(tile.Level); 58 double x = 0 + tile.X * width; 59 double y = /*minY*/0 + tile.Y * height; 60 61 DataRect bounds = new DataRect(x, y, width, height); 62 return bounds; 63 } 64 65 private bool xCycling = true; 66 /// <summary> 67 /// Gets or sets a value, indicating whether use cycled x coordinate. 68 /// </summary> 69 public bool XCycling 70 { 71 get { return xCycling; } 72 set { xCycling = value; } 73 } 74 75 // todo rewrite 76 public static IEnumerable<TileIndex> GetTilesForLevel(double level) 77 { 78 int size = GetSideTilesCount(level) / 2; 79 for (int x = -size; x < size; x++) 80 { 81 for (int y = -size; y < size; y++) 82 { 83 yield return new TileIndex(x, y, level); 84 } 85 } 86 } 87 88 public static DataRect GetTileBoundsGeneric(TileIndex tile) 89 { 90 double width = 360.0 / Math.Pow(2, tile.Level); 91 double height = 174.0 / Math.Pow(2, tile.Level); 92 double x = /*minX*/0 + tile.X * width; 93 double y = /*minY*/0 + tile.Y * height; 94 95 DataRect bounds = new DataRect(x, y, width, height); 96 return bounds; 97 } 98 99 public static long GetTotalTilesCount(double level) 100 { 101 long size = GetSideTilesCount(level); 102 return size * size; 103 } 104 105 public static int GetSideTilesCount(double level) 106 { 107 return (int)Math.Pow(2, level); 108 } 109 110 public double TileWidth { get { return GetTileWidth(Level); } } 111 public double TileHeight { get { return GetTileHeight(Level); } } 112 113 public override double GetTileWidth(double level) 114 { 115 return XSize / Math.Pow(2, level); 116 } 117 118 public override double GetTileHeight(double level) 119 { 120 return YSize / Math.Pow(2, level); 121 } 122 123 public override IEnumerable<TileIndex> GetTilesForRegion(DataRect region, double level) 124 { 125 var allTilesBounds = rect; 126 if (xCycling) 127 allTilesBounds = DataRect.Create(-Double.MaxValue, -MaxLatitude, Double.MaxValue, MaxLatitude); 128 129 region.Intersect(allTilesBounds); 130 //region.Intersect(new Rect(region.XMin, minY, region.Width, maxY - minY)); 131 if (region.IsEmpty) 132 yield break; 133 134 checked 135 { 136 double tileWidth = TileWidth; 137 double tileHeight = TileHeight; 138 139 int minIx = (int)Math.Floor(region.XMin / tileWidth); 140 int maxIx = (int)Math.Ceiling(region.XMax / tileWidth); 141 142 int minIy = (int)Math.Floor(region.YMin / tileHeight); 143 int maxIy = (int)Math.Ceiling(region.YMax / tileHeight); 144 145 var maxSideCount = GetSideTilesCount(Level); 146 147 int maxIndex = maxSideCount / 2; 148 if (!xCycling) 149 { 150 if (maxIx > maxIndex) 151 maxIx = maxIndex; 152 if (minIx < -maxIndex) 153 minIx = -maxIndex; 154 } 155 if (maxIy > maxIndex) 156 maxIy = maxIndex; 157 if (minIy < -maxIndex) 158 minIy = -maxIndex; 159 160 if (level != 0) 161 { 162 maxIx--; 163 maxIy--; 164 } 165 166 for (int ix = minIx; ix <= maxIx; ix++) 167 { 168 for (int iy = minIy; iy <= maxIy; iy++) 169 { 170 yield return new TileIndex(ix, iy, level); 171 } 172 } 173 } 174 } 175 176 public static TileIndex NormalizeIndex(TileIndex id) 177 { 178 int actualX = id.X % GetSideTilesCount(id.Level); 179 TileIndex res = new TileIndex(actualX, id.Y, id.Level); 180 return res; 181 } 182 } 183}