PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

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