May 23, 2008

Google Maps Globe

I created a globe using Google Maps API for Flash.

It is impossible to get the image data by BitmapData.draw(), so I used a DisplacementMapFilter.

Here is the code(70 lines):

  1. package {
  2.     import flash.display.*;
  3.     import flash.geom.*;
  4.     import flash.filters.DisplacementMapFilter;
  5.     import flash.utils.setInterval;
  6.     import com.google.maps.*;
  7.  
  8.     [SWF(backgroundColor="0x000000")]
  9.     public class GoogleEarthAs3_2 extends Sprite {
  10.         private const WIDTH:int = 800;
  11.         private const HEIGHT:int = 500;
  12.         private const RADIUS:int = 81;
  13.         private var map:Map;
  14.  
  15.         public function GoogleEarthAs3_2() {
  16.             stage.scaleMode = "noScale";
  17.             stage.align = "TL";
  18.  
  19.             map = new Map();
  20.             map.key = "ABQIAAAA6de2NwhEAYfH7t7oAYcX3xRWPxFShKMZYAUclLzloAj2mNQgoRQZnk8BRyG0g_m2di3bWaT-Ji54Lg";
  21.             map.setSize(new Point(800, 500));
  22.             map.addEventListener(MapEvent.MAP_READY, function(event:*):void{
  23.                 var lng:Number = 0;
  24.                 var types:Array = [MapType.SATELLITE_MAP_TYPE, MapType.PHYSICAL_MAP_TYPE, MapType.NORMAL_MAP_TYPE];
  25.                 var type:int = 0;
  26.                 map.setCenter(new LatLng(0, lng), 1, types[0]);
  27.                 map.disableDragging();
  28.  
  29.                 setInterval(function():void
  30.                 {
  31.                     lng -= 3;
  32.                     type = Math.random() < 0.05 ? (type + 1) % 3 : type;
  33.                     map.setCenter(new LatLng(0, lng), 1, types[type]);
  34.                     lng = lng % 360;
  35.                 }, 200);
  36.             });
  37.  
  38.             var bmd:BitmapData = new BitmapData(WIDTH, HEIGHT, false, 0);
  39.             for(var j:int = 0; j < RADIUS * 2; j++){
  40.                 var ay:Number = Math.PI / 2 - Math.acos(1 - j / RADIUS);
  41.                 var dy:Number = RADIUS - j - RADIUS * ay;
  42.                 var rx:Number = RADIUS * Math.cos(ay);
  43.                 for(var i:int = RADIUS - rx; i < RADIUS + rx; i++){
  44.                     var ax:Number = Math.PI / 2 - Math.acos(1 - (i - RADIUS + rx) / rx);
  45.                     var dx:Number = RADIUS - i - rx * ax;
  46.  
  47.                     bmd.setPixel(i, j, getColor(dx * 3 + 128, dy * 3 + 128, 128));
  48.                 }
  49.             }
  50.  
  51.             var diff:Number = (HEIGHT - 2 * RADIUS) / 2;
  52.             map.filters = [new DisplacementMapFilter(bmd, new Point(diff, diff), 1, 2, 128, 128)];
  53.             var matrix:Matrix = new Matrix();
  54.             matrix.translate(-diff, -diff);
  55.             map.transform.matrix = matrix;
  56.             addChild(map);
  57.  
  58.             var msk:Sprite = new Sprite();
  59.             msk.graphics.beginFill(0);
  60.             msk.graphics.drawCircle(RADIUS, RADIUS, RADIUS);
  61.             msk.graphics.endFill();
  62.             addChild(msk);
  63.             mask = msk;
  64.         }
  65.  
  66.         private static function getColor(r:int, g:int, b:int):uint {
  67.             return r * 0x10000 + g * 0x100 + b;
  68.         }
  69.     }
  70. }