PageRenderTime 40ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/google/maps/extras/arcgislink/ArcGISTileConfig.as

http://gmaps-utility-library-flash.googlecode.com/
ActionScript | 209 lines | 100 code | 24 blank | 85 comment | 18 complexity | 6e6ce677a3bd712c9a9de57160b2973f MD5 | raw file
  1. /*
  2. * ArcGIS for Google Maps Flash API
  3. *
  4. * License http://www.apache.org/licenses/LICENSE-2.0
  5. */
  6. /**
  7. * @author nianwei at gmail dot com
  8. */
  9. package com.google.maps.extras.arcgislink {
  10. import com.google.maps.*;
  11. import com.google.maps.interfaces.*;
  12. import flash.geom.Point;
  13. /**
  14. * This class is a bridge between Google's projection and ArcGIS's spatial reference system.
  15. */
  16. public class ArcGISTileConfig extends ProjectionBase {
  17. private var tileInfo_:*;
  18. private var spatialReference_:SpatialReference;
  19. internal var zoomOffset_:int; //used in TileLayer
  20. private var fullExtent_:*;
  21. public function ArcGISTileConfig( /*TileInfo*/ tileInfo:*, /*Envelope*/ opt_fullExtent:*=null) {
  22. super();
  23. if (!tileInfo) {
  24. throw new Error('map service is not tiled');
  25. }
  26. this.tileInfo_=tileInfo;
  27. this.spatialReference_=SpatialReferences.getSpatialReference(tileInfo.spatialReference.wkid);
  28. if (!this.spatialReference_) {
  29. throw new Error('unsupported Spatial Reference: ' + tileInfo.spatialReference.wkid);
  30. }
  31. this.zoomOffset_=Math.floor(Math.log(this.spatialReference_.getCircumference() / this.tileInfo_.lods[0].resolution / 256) / Math.LN2 + 0.5);
  32. this.fullExtent_=opt_fullExtent;
  33. }
  34. /**
  35. * See <a href = 'http://code.google.com/apis/maps/documentation/reference.html#GProjection'>GProjection</a>.
  36. * @param {GLatLng} gLatLng
  37. * @param {Number} zoom
  38. * @return {GPoint} pixel
  39. */
  40. override public function fromLatLngToPixel(gLatLng:LatLng, zoom:Number):flash.geom.Point {
  41. if (!gLatLng || isNaN(gLatLng.lat()) || isNaN(gLatLng.lng())) {
  42. return null;
  43. }
  44. var coords:Array=this.spatialReference_.forward([gLatLng.lng(), gLatLng.lat()]);
  45. var zoomIdx:int=zoom - this.zoomOffset_;
  46. var res:Number=this.getUnitsPerPixel(zoom);
  47. //!!!! must NOT round to integer, even it is fine in JS version, Flex version
  48. // will cause HUGE shift!
  49. var px:Number=(coords[0] - (this.tileInfo_.origin.x as Number)) / res;
  50. var py:Number=((this.tileInfo_.origin.y as Number) - coords[1]) / res;
  51. return new Point(px, py);
  52. }
  53. /**
  54. * Get resolution (Units per Pixel) at given zoom level.
  55. * @param {Number} zoom
  56. * @return Number
  57. */
  58. public function getUnitsPerPixel(zoom:int):Number {
  59. var zoomIdx:int=zoom - this.zoomOffset_;
  60. var res:Number=Number.MAX_VALUE;
  61. var factor:Number = 1;
  62. if (zoomIdx <0){
  63. // trace('invalid zoom: ' +zoom);
  64. factor = Math.pow(2, -zoomIdx);
  65. res=this.tileInfo_.lods[0].resolution * factor;
  66. } else if (zoomIdx > this.tileInfo_.lods.length-1){
  67. // trace('invalid zoom: ' +zoom);
  68. factor=Math.pow(2, zoom - this.maxResolution());
  69. res=this.tileInfo_.lods[this.tileInfo_.lods.length - 1].resolution / factor;
  70. } else {
  71. res=this.tileInfo_.lods[zoomIdx].resolution;
  72. }
  73. return res;
  74. }
  75. /**
  76. * Get the scale at given level;
  77. * @param {Number} zoom
  78. * @return {Number}
  79. public function getScale(zoom:int):Number {
  80. var zoomIdx:int=zoom - this.zoomOffset_;
  81. var res:Number=0;
  82. if (this.tileInfo_.lods[zoomIdx]) {
  83. res=this.tileInfo_.lods[zoomIdx].scale;
  84. } else {
  85. //this is a special case when the maxZoom is set larger than what's actually defined in the tiling scheme.
  86. // the goal is to allow map continue to zoom to extremely detail level by using ArcGISMapOverlay.
  87. var factor:Number=Math.pow(2, zoom - this.maxResolution());
  88. res=this.tileInfo_.lods[this.tileInfo_.lods.length - 1].scale / factor;
  89. }
  90. return res;
  91. }
  92. */
  93. /**
  94. * See <a href = 'http://code.google.com/apis/maps/documentation/reference.html#GProjection'>GProjection</a>.
  95. * @param {GPoint} pixel
  96. * @param {Number} zoom
  97. * @param {Boolean} unbound
  98. * @return {GLatLng} gLatLng
  99. */
  100. override public function fromPixelToLatLng(pixel:flash.geom.Point, zoom:Number, unbound:Boolean=false):LatLng {
  101. if (pixel === null) {
  102. return null;
  103. }
  104. var zoomIdx:int=zoom - this.zoomOffset_;
  105. var res:Number=this.getUnitsPerPixel(zoom);
  106. var x:Number=pixel.x * res + (this.tileInfo_.origin.x as Number);
  107. var y:Number=(this.tileInfo_.origin.y as Number)- pixel.y * res;
  108. var ll:Array=this.spatialReference_.reverse([x, y]);
  109. return new LatLng(ll[1], ll[0]);
  110. }
  111. /**
  112. * See <a href = 'http://code.google.com/apis/maps/documentation/reference.html#GProjection'>GProjection</a>.
  113. * @param {Object} tile
  114. * @param {Number} zoom
  115. * @param {Number} tilesize
  116. */
  117. override public function tileCheckRange(tile:flash.geom.Point, zoom:Number, tilesize:Number):Boolean {
  118. var zoomIdx:Number=zoom - this.zoomOffset_;
  119. if (this.tileInfo_.lods[zoomIdx]) {
  120. var b:*=this.fullExtent_;
  121. if (!b) {
  122. return true;
  123. }
  124. var minX:Number=tile.x * tilesize * this.tileInfo_.lods[zoomIdx].resolution + this.tileInfo_.origin.x;
  125. var minY:Number=this.tileInfo_.origin.y - (tile.y + 1) * tilesize * this.tileInfo_.lods[zoomIdx].resolution;
  126. var maxX:Number=(tile.x + 1) * tilesize * this.tileInfo_.lods[zoomIdx].resolution + this.tileInfo_.origin.x;
  127. var maxY:Number=this.tileInfo_.origin.y - tile.y * tilesize * this.tileInfo_.lods[zoomIdx].resolution;
  128. var ret:Boolean=!(b.xmin > maxX || b.xmax < minX || b.ymax < minY || b.ymin > maxY);
  129. return ret;
  130. } else {
  131. return false;
  132. }
  133. }
  134. /**
  135. * See <a href = 'http://code.google.com/apis/maps/documentation/reference.html#GProjection'>GProjection</a>.
  136. * @param {Number} zoom
  137. * @return {Number} numOfpixel
  138. */
  139. override public function getWrapWidth(zoom:Number):Number {
  140. var zoomIdx:Number=zoom - this.zoomOffset_;
  141. if (this.tileInfo_.lods[zoomIdx]) {
  142. return this.spatialReference_.getCircumference() / this.tileInfo_.lods[zoomIdx].resolution;
  143. } else {
  144. return Number.MAX_VALUE;
  145. }
  146. }
  147. /**
  148. * Get the tile size used by this Projection. Shortcut to tileInfo.rows;
  149. * @return {Number}
  150. */
  151. public function getTileSize():Number {
  152. return this.tileInfo_.rows;
  153. }
  154. /**
  155. * Get min zoom level of actual tiles
  156. * @return {Number}
  157. */
  158. public function minResolution():Number {
  159. return this.zoomOffset_;
  160. }
  161. /**
  162. * Get max zoom level of actual tiles
  163. * @return {Number}
  164. */
  165. public function maxResolution():Number {
  166. return this.zoomOffset_ + this.tileInfo_.lods.length - 1;
  167. }
  168. /**
  169. * Get the underline {@link ArcGISSpatialReference}
  170. * @return {ArcGISSpatialReference}
  171. */
  172. public function getSpatialReference():SpatialReference {
  173. return this.spatialReference_;
  174. }
  175. /**
  176. *tile configuration used by Google Maps
  177. */
  178. public static const GOOGLE_MAPS:ArcGISTileConfig=new ArcGISTileConfig({"rows": 256, "cols": 256, "dpi": 96, "format": "PNG8", "compressionQuality": 0, "origin": {"x": -20037508.342787, "y": 20037508.342787}, "spatialReference": {"wkid": 102113}, "lods": [{"level": 0, "resolution": 156543.033928, "scale": 591657527.591555}, {"level": 1, "resolution": 78271.5169639999, "scale": 295828763.795777}, {"level": 2, "resolution": 39135.7584820001, "scale": 147914381.897889}, {"level": 3, "resolution": 19567.8792409999, "scale": 73957190.948944}, {"level": 4, "resolution": 9783.93962049996, "scale": 36978595.474472}, {"level": 5, "resolution": 4891.96981024998, "scale": 18489297.737236}, {"level": 6, "resolution": 2445.98490512499, "scale": 9244648.868618}, {"level": 7, "resolution": 1222.99245256249, "scale": 4622324.434309}, {"level": 8, "resolution": 611.49622628138, "scale": 2311162.217155}, {"level": 9, "resolution": 305.748113140558, "scale": 1155581.108577}, {"level": 10, "resolution": 152.874056570411, "scale": 577790.554289}, {"level": 11, "resolution": 76.4370282850732, "scale": 288895.277144}, {"level": 12, "resolution": 38.2185141425366, "scale": 144447.638572}, {"level": 13, "resolution": 19.1092570712683, "scale": 72223.819286}, {"level": 14, "resolution": 9.55462853563415, "scale": 36111.909643}, {"level": 15, "resolution": 4.77731426794937, "scale": 18055.954822}, {"level": 16, "resolution": 2.38865713397468, "scale": 9027.977411}, {"level": 17, "resolution": 1.19432856685505, "scale": 4513.988705}, {"level": 18, "resolution": 0.597164283559817, "scale": 2256.994353}, {"level": 19, "resolution": 0.298582141647617, "scale": 1128.497176}]}, null);
  179. /**
  180. *tile configuration used by ArcGIS online
  181. */
  182. public static const ARCGIS_ONLINE:ArcGISTileConfig=new ArcGISTileConfig({"rows": 512, "cols": 512, "dpi": 96, "origin": {"x": -180, "y": 90}, "spatialReference": {"wkid": 4326}, "lods": [{"level": 0, "resolution": 0.351562499999999, "scale": 147748799.285417}, {"level": 1, "resolution": 0.17578125, "scale": 73874399.6427087}, {"level": 2, "resolution": 0.0878906250000001, "scale": 36937199.8213544}, {"level": 3, "resolution": 0.0439453125, "scale": 18468599.9106772}, {"level": 4, "resolution": 0.02197265625, "scale": 9234299.95533859}, {"level": 5, "resolution": 0.010986328125, "scale": 4617149.97766929}, {"level": 6, "resolution": 0.0054931640625, "scale": 2308574.98883465}, {"level": 7, "resolution": 0.00274658203124999, "scale": 1154287.49441732}, {"level": 8, "resolution": 0.001373291015625, "scale": 577143.747208662}, {"level": 9, "resolution": 0.0006866455078125, "scale": 288571.873604331}, {"level": 10, "resolution": 0.000343322753906249, "scale": 144285.936802165}, {"level": 11, "resolution": 0.000171661376953125, "scale": 72142.9684010827}, {"level": 12, "resolution": 8.58306884765626E-05, "scale": 36071.4842005414}, {"level": 13, "resolution": 4.29153442382813E-05, "scale": 18035.7421002707}, {"level": 14, "resolution": 2.14576721191406E-05, "scale": 9017.87105013534}, {"level": 15, "resolution": 1.07288360595703E-05, "scale": 4508.93552506767}]});
  183. }
  184. }