2011年02月28日
Google Maps をジオラマ風にしてみた
Google Maps をジオラマ写真風にすると印象が変わる、というアイディアが チルトシフトの新しい使い方 その2 に書いてあった。
おもしろそうなのでリアルタイムに Google Maps をジオラマ風に表示するものを作ってみた。
好きな場所を表示できるので、地球全体がジオラマになってしまった。
簡単な使い方:
- 上部の検索欄に英語で入力して移動
- 左のコントロールは Google Maps と同じ
- Shift+ドラッグで視点移動
日本各地を巡ってみた
東京駅前
車がミニチュア風でかわいい。
京都御所
箱庭になりました。
大阪駅上空
線路と高速道路とビル群。鉄道模型みたい。
どうぞご利用ください
あなたの街をジオラマ風に!
ソースコード
チルトシフトのエフェクトは「彩度をあげる」「周りをぼかす」「周りを暗くする」ことで実現している。
ソースコードは以下に(map_1_20.swc、minimalcomps、Tweener を利用)。
// Diorama Google Maps //------------------------------------------------------------------- // This flash changes google maps to tilt-shift photography. // inspired by http://reinit.info/blog/archive/2011/02/23/tiltshift_2/ package { import flash.events.*; import flash.display.*; import flash.geom.*; import flash.filters.*; import com.google.maps.*; import com.google.maps.geom.*; import com.google.maps.controls.*; import com.google.maps.services.*; import com.bit101.components.*; import caurina.transitions.Tweener; public class DioramaGoogleMaps extends Sprite { private static var WIDTH:Number = 475; private static var HEIGHT:Number = 475; private static var BLUR_PARAM:Number = 160; private static var CONTROL_ALPHA:Number = 0.3; private var maps:Array = []; private var controls:Sprite; public function DioramaGoogleMaps():void { stage.scaleMode = "noScale"; stage.align = "TL"; stage.stageFocusRect = false; // blurred map var map1:Map3D = createMap(true); map1.filters = [new BlurFilter(6, 6), getSaturationFilter(2.8)]; addChild(map1); // normal map var map2:Map3D = createMap(false); map2.filters = [getSaturationFilter(1.8)]; map2.cacheAsBitmap = true; addChild(map2); var msk:Sprite = new Sprite(); msk.graphics.beginFill(0); msk.graphics.drawEllipse(-WIDTH * 0.5, -HEIGHT * 0.3, WIDTH * 1.0, HEIGHT * 0.6); msk.graphics.endFill(); msk.x = WIDTH * 0.5 msk.y = HEIGHT * 0.5 msk.filters = [new BlurFilter(BLUR_PARAM, BLUR_PARAM)]; msk.cacheAsBitmap = true; addChild(msk); map2.mask = msk; maps = [map1, map2]; // limb darkening filters = [new GlowFilter(0, 0.3, BLUR_PARAM, BLUR_PARAM, 1, 1, true)]; // add control initControl(); } private function initControl():void{ controls = new Sprite(); var search:Sprite = new Sprite(); search.x = 240; search.y = 10; search.scaleX = search.scaleY = 1.5; // text var txt:InputText = new InputText(controls, 0, 0); txt.width = 100; txt.addEventListener("keyDown", function(event:KeyboardEvent):void{ if (event.keyCode == 13) { btn.dispatchEvent(new Event("click")); } }); search.addChild(txt); // button var btn:PushButton = new PushButton(search, 100, 0, "Search", function(event:Event):void{ var geo:ClientGeocoder = new ClientGeocoder(); geo.geocode(txt.text); geo.addEventListener("geocodingsuccess", function(event:GeocodingEvent):void{ var marks:Array = event.response.placemarks; var map:Map3D = maps[0] as Map3D; if (marks.length > 0){ map.flyTo(marks[0].point, 15, new Attitude(20, 30, 0), 1); } }); geo.addEventListener("geocodingfailure", function(event:GeocodingEvent):void{ txt.text = "NOT FOUND"; }); }); btn.width = 50; btn.height = txt.height; controls.addChild(search); addChild(controls); controls.alpha = CONTROL_ALPHA; controls.addEventListener("mouseOver", function(event:Event):void { Tweener.addTween(controls, {alpha: 0.9, time: 0.5 }); }); controls.addEventListener("mouseOut", function(event:Event):void { Tweener.addTween(controls, {alpha: CONTROL_ALPHA, time: 0.5 }); }) } // create a map private function createMap(isBlur:Boolean):Map3D{ var map:Map3D = new Map3D(); map.key = "ABQIAAAA6de2NwhEAYfH7t7oAYcX3xRWPxFShKMZYAUclLzloAj2mNQgoRQZnk8BRyG0g_m2di3bWaT-Ji54Lg"; map.sensor = "false"; map.setSize(new Point(WIDTH, HEIGHT)); map.addEventListener(MapEvent.MAP_PREINITIALIZE, function(event:Event):void{ map.setInitOptions(new MapOptions({ zoom: 16.6, center: new LatLng(48.873847, 2.29502), mapType: MapType.SATELLITE_MAP_TYPE, viewMode: View.VIEWMODE_ORTHOGONAL, attitude: new Attitude(20, 30, 0), doubleClickMode: MapAction.ACTION_PAN_ZOOM_IN, mouseClickRange: 2 })); }); map.addEventListener(MapEvent.MAP_READY, function(event:Event):void{ if (!isBlur){ var control:NavigationControl = new NavigationControl(new NavigationControlOptions({ position: new ControlPosition(ControlPosition.ANCHOR_TOP_LEFT, 5) })); map.addControl(control); // move to control sprite var obj:DisplayObject = control.getDisplayObject(); if (obj.parent){ obj.parent.removeChild(obj); controls.addChild(obj); } } }); map.addEventListener("mapevent_movestep", changeHandler); map.addEventListener("mapevent_moveend", changeHandler); map.addEventListener("mapevent_zoomend", changeHandler); map.addEventListener("mapevent_attitudechangeend", changeHandler); map.addEventListener("mapevent_attitudechangestep", changeHandler); return map; } // sync two map private function changeHandler(event:Event):void{ if(maps.length != 2) return; var me:Map3D = event.target as Map3D; var other:Map3D = (me == maps[0] ? maps[1] : maps[0]) as Map3D; var c1:LatLng = me.getCenter(); var z1:Number = me.getZoom(); var a1:Attitude = me.getAttitude(); if(!c1.equals(other.getCenter())){ other.setCenter(c1); } if(z1 != other.getZoom()){ other.setZoom(z1); } if(!a1.equals(other.getAttitude())){ other.setAttitude(a1) } } private static var LUMINANCE_R:Number = 0.212671; private static var LUMINANCE_G:Number = 0.715160; private static var LUMINANCE_B:Number = 0.072169; private function getSaturationFilter(saturation:Number):BitmapFilter{ var sf:Number = saturation; var nf:Number = 1-sf; var nr:Number = LUMINANCE_R * nf; var ng:Number = LUMINANCE_G * nf; var nb:Number = LUMINANCE_B * nf; return new ColorMatrixFilter([ nr+sf, ng, nb, 0, 0, nr, ng+sf, nb, 0, 0, nr, ng, nb+sf, 0, 0, 0, 0, 0, 1, 0 ]); } } }