Top Banner
Geo×HTML5 on MapsAPI QuickHandson(3分クッキング) 春のGoogle勉強会 in高松 2013/3/17 石丸健太郎(@kehi GDG信州Manager & GDE Maps) 13324日日曜日
47

Gdg geo2

Dec 05, 2014

Download

Technology

kehi

Geo x HTML5 on MapsAPI QuickHandson
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Gdg geo2

Geo×HTML5 on MapsAPI�QuickHandson(3分クッキング)

春のGoogle勉強会 in高松�2013/3/17 石丸健太郎(@kehi GDG信州Manager & GDE Maps)

13年3月24日日曜日

Page 2: Gdg geo2

Menu����������●Geo系API紹介篇�〜プレーンな地図からトッピング感覚で作ってみよう〜

1. 現在地取得と地名検索(Geolocation�&�Geocoding)2. 地図と連動したストリートビューを表示(StreetView)3. 地図に道案内を表示(DirectionsAPI)4. �地図中のデータをカスタマイズ(StyledMap)

●Geo系API実践篇�〜�きっと役に立つ様々なTipsをご紹介〜5. ���様々なマーカー表示とパフォーマンスTips6. ���応用技で使いこなすStaticMapsAPI7. ���位置情報付きのURIを実装するメリット8. ���スマホ向けサイトをスマートに表示9. ���Canvasを使って画像ファイルをLocalStorageに記録 �10. ���パノラマ写真でマイストリートビューを実現

●Geo系API番外篇�����������・FirefoxOSを試す������������・MapsAPIの制限に関する誤解?!������������・0から1を生み出す為に

SampleCode: http://googlemaps.geo.jp/gdg2/

13年3月24日日曜日

Page 3: Gdg geo2

Menu����������●Geo系API紹介篇�〜プレーンな地図からトッピング感覚で作ってみよう〜

1. 現在地取得と地名検索(Geolocation�&�Geocoding)2. 地図と連動したストリートビューを表示(StreetView)3. 地図に道案内を表示(DirectionsAPI)4. �地図中のデータをカスタマイズ(StyledMap)

●Geo系API実践篇�〜�きっと役に立つ様々なTipsをご紹介〜5. ���様々なマーカー表示とパフォーマンスTips6. ���応用技で使いこなすStaticMapsAPI7. ���位置情報付きのURIを実装するメリット8. ���スマホ向けサイトをスマートに表示9. ���Canvasを使って画像ファイルをLocalStorageに記録 �10. ���パノラマ写真でマイストリートビューを実現

●Geo系API番外篇�����������・FirefoxOSを試す������������・MapsAPIの制限に関する誤解?!������������・0から1を生み出す為に

SampleCode: http://googlemaps.geo.jp/gdg2/

13年3月24日日曜日

Page 4: Gdg geo2

It’s real iceBreak?!

きっとご利益のある2年連続の諏訪湖の御神渡り

13年3月24日日曜日

Page 5: Gdg geo2

Recipe1-1:�現在地を取得して地図を表示

完成図 材料・MapsAPI V3(JavaScriptAPI)

・GeolocationAPI(HTML5)

作り方作り方Sample1:1度だけ位置情報を取得して表示する

Sample2:誤差や計測回数を条件にして精度の高い位置情報を取得する

API Referencehttp://code.google.com/intl/ja/apis/maps/documentation/javascript/basics.html#Geolocationhttp://dev.w3.org/geo/api/spec-source.html

13年3月24日日曜日

Page 6: Gdg geo2

// 位置情報を受信した時の処理function update(position){ var lat = position.coords.latitude; var lng = position.coords.longitude; var currentPos = new google.maps.LatLng(lat, lng); map.setCenter(currentPos);

//位置の探索を終了navigator.geolocation.clearWatch(wid);

}

①位置取得(GeoLocationAPI)

 一度だけ取得:navigator.geolocation.getCurrentPosition(success,error,option);

定期的に取得:navigator.geolocation.watchPosition(success,error,option);

GeoLocationAPI

13年3月24日日曜日

Page 7: Gdg geo2

Data Get

var httpObj = createHttpRequest();httpObj.open("GET",url,true);httpObj.onreadystatechange = function() { if (httpObj.readyState == 4 && httpObj.status == 200){ if(httpObj.responseText != ""){ obj = eval("("+httpObj.responseText+")"); } } httpObj.send(null);}

$(function() { $.getJSON("data.json",function(obj){ hoge(obj); });});

13年3月24日日曜日

Page 8: Gdg geo2

8

//マーカーの消去は自分でfunction clearOverlays() { if (markersArray) { for (i in markersArray) { markersArray[i].setMap(null); } }}markersArray.push(marker);

//infoWindowの消去も自分でgoogle.maps.event.addListener(marker, "click", function() { infowindow = new google.maps.InfoWindow({ content: html }); if (currentInfoWindow) { currentInfoWindow.close(); } infowindow.open(map, marker); currentInfoWindow = infowindow;

});

Do it yourself

13年3月24日日曜日

Page 9: Gdg geo2

Recipe1-2:�地名で検索して地図を表示

完成図 材料・MapsAPI V3(JavaScriptAPI)

・GeocodingAPI(Geo)

作り方作り方Sample1:自由入力した地名を検索して遷移

JavaScriptだけでなくHTTPによる呼び出しも可能(サーバ処理で便利)

API Referencehttp://code.google.com/intl/ja/apis/maps/documentation/geocoding/

13年3月24日日曜日

Page 10: Gdg geo2

//JavaScript API var gc = new google.maps.Geocoder(); gc.geocode({ address : adrs }, function(results, status){ if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); }else{ alert(status+" : 場所が見つかりませんでした"); } });

Geocoding

http://maps.googleapis.com/maps/api/geocode/json?address=地名&sensor=true or false

//HTTP Geocoding API

※所在地→緯度経度だけでなく、緯度経度→所在地(逆Geocoding)も対応 

13年3月24日日曜日

Page 11: Gdg geo2

Recipe2:�地図と連動したストリートビューを表示

完成図 材料・MapsAPI V3(JavaScriptAPI)

 →.StreetViewPanorama

作り方作り方Sample1:ペグマンから表示Sample2:API経由で自由な位置に表示

API Referencehttp://code.google.com/intl/ja/apis/maps/documentation/javascript/services.html#StreetView

13年3月24日日曜日

Page 12: Gdg geo2

// ストリートビュー var svp = new google.maps.StreetViewPanorama( document.getElementById("streetview"), { position : new google.maps.LatLng(lat,lng) } ); if(svp.getVisible()){ map.setStreetView(svp); }

StreetView

13年3月24日日曜日

Page 13: Gdg geo2

Recipe3:�地図に道案内を表示

完成図 材料・MapsAPI V3(JavaScriptAPI)

・DerectionsAPI(Geo)・DistanceMatrixAPI(Geo)

作り方作り方Sample1:道案内を設置するSample2:中間地点の文字を変更Sample3:距離を計測

API Reference http://code.google.com/intl/ja/apis/maps/documentation/directions/ https://developers.google.com/maps/documentation/distancematrix/?hl=ja

13年3月24日日曜日

Page 14: Gdg geo2

14

//ディレクション(道案内)var directionsRenderer = new google.maps.DirectionsRenderer(rendererOptions);directionsRenderer.setMap(map);var request = { origin: point1, destination: point2, travelMode: google.maps.DirectionsTravelMode.WALKING};var directionsService = new google.maps.DirectionsService();directionsService.route(request, function(result, status){ if (status == google.maps.DirectionsStatus.OK) { directionsRenderer.setDirections(result); }});

Directions

13年3月24日日曜日

Page 15: Gdg geo2

完成図 材料・StyledMapType

ex)Clean Air Asia

作り方作り方Sample1:StyledMapWizardでカスタマイズしたStaticMapを生成Sample2:地図を夜にする?!

StyledMapWizard http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html

Recipe4:�StyledMapで地図中のデータをカスタマイズ

13年3月24日日曜日

Page 16: Gdg geo2

Menu����������●Geo系API紹介篇�〜プレーンな地図からトッピング感覚で作ってみよう〜

1. 現在地取得と地名検索(Geolocation�&�Geocoding)2. 地図と連動したストリートビューを表示(StreetView)3. 地図に道案内を表示(DirectionsAPI)4. �地図中のデータをカスタマイズ(StyledMap)

●Geo系API実践篇�〜�きっと役に立つ様々なTipsをご紹介〜5. ���様々なマーカー表示とパフォーマンスTips6. ���応用技で使いこなすStaticMapsAPI7. ���位置情報付きのURIを実装するメリット8. ���スマホ向けサイトをスマートに表示9. ���Canvasを使って画像ファイルをLocalStorageに記録 �10. ���パノラマ写真でマイストリートビューを実現

●Geo系API番外篇�����������・FirefoxOSを試す������������・MapsAPIの制限に関する誤解?!������������・0から1を生み出す為に

SampleCode: http://googlemaps.geo.jp/gdg2/

13年3月24日日曜日

Page 17: Gdg geo2

完成図 材料・MapsAPI V3(JavaScriptAPI)

・JQuery

作り方作り方Sample1:矩形領域を指定して都度Ajax通信後マーカーを都度表示Sample2:すべてのマーカー情報を受け取り後、矩形領域のみマーカーを表示

Which is faster ? 単品注文 vs 全部入り どっちがウマい?

Recipe5:�マーカー表示のパフォーマンスTips

13年3月24日日曜日

Page 18: Gdg geo2

・地図をグリグリ動かして使うことを想定させるコンテンツ・PC向けサイト

・一度計測したらほぼ動かす必要のないコンテンツ・モバイル端末

=2回以上なら全部読み・・だが?!

Event 都度読込み 全部読込み

JS処理 10ms/avg 112ms/avgネットワーク 617ms/毎回 初回1290ms 

2回目以降 0ms

FireBugで計測console.time();・・・・ マーカー呼出処理・・・・ console.timeEnd();

Which is faster? マーカー都度読み込み VS 全部読み どっちが速い?

全部

都度

13年3月24日日曜日

Page 19: Gdg geo2

http://www.fusonic.net/en/blog/2009/12/11/clustering-for-google-maps-v3-with-fluster2/MarkerClusteringの例

https://developers.google.com/maps/documentation/javascript/layers#JSHeatMapsJS HeatMapの例

Tips : 位置情報の様々な表現方法

Other(FusionTables)https://googlemaps.geo.jp/gdg2/5/sample3.html

コンテンツ容量やネットワーク速度対策だけでなく描画すべきコンテンツが多い場合はマーカーの表現方法を変えるのが効果的!

13年3月24日日曜日

Page 20: Gdg geo2

//For Clientrc = map.getBounds();mapArea = rc.getSouthWest() +","+rc.getNorthEast();var url = "http://hoge/fuga.php?ll="+mapArea+"&cache="+(new Date()).getTime();var httpObj = createHttpRequest();httpObj.open("GET",url,true);httpObj.send(null);

//For Server$sql = "SELECT * FROM hoge where ((lat BETWEEN $swlat and $nelat) and (lng BETWEEN $swlng and $nelng))";

//圧縮送信も効果的PHPならob-gzhandler 1行!

SW(lat,lng)

NE(lat,lng)

Tips : 緯度経度取得

13年3月24日日曜日

Page 21: Gdg geo2

Recipe6:�応用技で使いこなすStaticMapsAPI

完成図 材料・MapsAPI V3(JavaScriptAPI)

・StreetView ImageAPI(ImageAPIs)・StaticMapsAPI V2 (ImageAPIs)・DerectionsAPI(Geo)

作り方作り方Sample1:Streetviewで表示と同場所同角度の静止画を表示Sample2:それぞれのscale指定を比較Sample3:スタティックなルート表示Sample4:出発地点と到着地点を独立表示

API Reference http://code.google.com/intl/ja/apis/maps/documentation/directions/http://code.google.com/intl/ja/apis/maps/documentation/streetview/

13年3月24日日曜日

Page 22: Gdg geo2

Recipe7:位置情報付きURIを実装するメリット

完成図 材料・URI

・URL Scheme

作り方作り方Sample1:(入口)他サイトやアプリからのスムーズな流入      →TwitterやFacebookからピンポイントに位置表示

Sample2:(出口)自サイトから他アプリへのスマートな遷移      →地図アプリで詳細を表示

参考:URLScheme developers.google.com/maps/documentation/ios/

urlscheme13年3月24日日曜日

Page 23: Gdg geo2

完成図 材料・HTML5(Form:range)・JqueryMobile

作り方作り方Sample1:スライダー表示

Sample2:GeolocationAPIのOptionsを制御

Recipe8:�スマホ向けサイトをスマートに作る

Examplehttp://codezine.jp/article/detail/5652?p=2

13年3月24日日曜日

Page 24: Gdg geo2

356pt [444pt]

60pt

20pt

44pt

④ 480pt

②416pt

①356pt

③460pt

320pt

Recipe8:�スマートフォンサイト対応のUI

※数値はViewPort値(ポイント)(Retinaのピクセル数は×2)※iOS6では縦幅が176px広がった分が表示幅にプラス(+88)

portrait

13年3月24日日曜日

Page 25: Gdg geo2

208pt

60pt

20pt

32pt

④ 320pt

②268pt

①356px

③300pt

480pt [568pt]

①208pt

Recipe8:�スマートフォンサイト対応のUI

landscape

13年3月24日日曜日

Page 26: Gdg geo2

Recipe8:�スマートフォンサイト対応のUI

13年3月24日日曜日

Page 27: Gdg geo2

Recipe8:�スマートフォンサイト対応のUI

① CSSで100%指定 →一番広く使えるとは限らない!

13年3月24日日曜日

Page 28: Gdg geo2

Recipe8:�スマートフォンサイト対応のUI

① CSSで100%指定 →一番広く使えるとは限らない!

② JavaScriptでアドレスバーを隠した場合(Scrollto)

13年3月24日日曜日

Page 29: Gdg geo2

Recipe8:�スマートフォンサイト対応のUI

① CSSで100%指定 →一番広く使えるとは限らない!

② JavaScriptでアドレスバーを隠した場合(Scrollto)

③ ホーム画面からの起動でフルスクリーン表示(blackモード)

13年3月24日日曜日

Page 30: Gdg geo2

Recipe8:�スマートフォンサイト対応のUI

④ ホーム画面からの起動でフルスクリーン表示(black-translucentモード)

④①

① CSSで100%指定 →一番広く使えるとは限らない!

② JavaScriptでアドレスバーを隠した場合(Scrollto)

③ ホーム画面からの起動でフルスクリーン表示(blackモード)

13年3月24日日曜日

Page 31: Gdg geo2

Recipe8:�スマートフォンサイト対応のUI

<link rel="stylesheet" media="all and (orientation:portrait)" href="iphone5_portrait.css"> //①<link rel="stylesheet" media="all and (orientation:landscape)" href="iphone5_landscape.css"> //②

#gmap { position : absolute; top:0px; left:0px; width: 568px; height:268px;}

#gmap { position : absolute; top:0px; left:0px; width: 320px; height:504px;}

① ②

iPhone4以前のピクセル指定のままだと隙間

iPhone4 iPhone5

13年3月24日日曜日

Page 32: Gdg geo2

完成図 材料・MapsAPI V3(JavaScriptAPI)

・PlacesAPI(Geo)・WebStorage(HTML5)・Canvas(HTML5)

作り方作り方Sample1: Canvasを使って画像ファイルをLocalStorageに記録

Recipe9: Canvasを使って画像をLocalStorageに記録

API Referencehttp://www.html5.jp/canvas/ref.html

13年3月24日日曜日

Page 33: Gdg geo2

完成図 材料・MapsAPI V3(JavaScriptAPI)  ※カスタムストリートビューの解説

・GeocodingAPI(Geo)・Form、FileAPI(HTML5)

作り方作り方・iPhone5標準のカメラでパノラマ写真撮影→180度なので2枚撮って合体 →写真のExifから緯度経度抽出(緯度経度から住所やランドマーク取得)  →画像のリサイズ(1024px × 2048px)と分割(縦4横8 / 256px/1)   →画像データをSQLiteに突っ込む    →StreetView APIで表示 →(゜Д゜)ウマー

ウマー

 

Recipe10: パノラマ写真でマイ・ストリートビューを実現

13年3月24日日曜日

Page 34: Gdg geo2

function getCustomPanoramaTileUrl(panoID, zoom, tileX, tileY) { return "/path/" + panoID + '/' + tileX + '_' +tileY + '.jpg';}function getCustomPanorama(panoID) { var streetViewPanoramaData = { links: [], copyright: 'kehi', tiles: { tileSize: new google.maps.Size(256, 256), worldSize: new google.maps.Size(2048, 1024), centerHeading: 0, getTileUrl: getCustomPanoramaTileUrl } };

Recipe10: パノラマ写真でマイ・ストリートビューを実現

3_0.jpg2_0.jpg1_0.jpg0_0.jpg

3_1.jpg2_1.jpg1_1.jpg0_1.jpg

4_0.jpg

3_2.jpg2_2.jpg1_2.jpg0_2.jpg

4_1.jpg

4_2.jpg

3_3.jpg2_3.jpg1_3.jpg0_3.jpg 4_3.jpg

13年3月24日日曜日

Page 35: Gdg geo2

1:パノラマ写真180度×2枚撮影(開始地点は真北heading0)(C)→HTML5からカメラアクセスhttp://dev.classmethod.jp/smartphone/ios6-safari-html5/

2:2枚をファイルアップロード(C)→MobileSafari対応(AndroidはVersionいくつから対応?

  Ajax方式→ http://d.hatena.ne.jp/takuya_1st/20121101/1351754417� 通常のPOST→� http://www.php-labo.net/tutorial/php/upload.html FileAPI経由のリサイズ→ http://blog.champierre.com/971

3:Exifから緯度経度を抽出(S)→PHPのExif_Read_dataから緯度経度の処理�������http://www.phppro.jp/qa/857

   →Client側でExif取得(jquery.exif.js)�

����������������http://www.nihilogic.dk/labs/exifjquery/

4:緯度経度から住所もしくはランドマークを取得→Google GeocodingAPI

https://developers.google.com/maps/documentation/geocoding/?hl=ja

5:緯度経度、ランドマーク、画像バイナリをSQLiteに登録http://jp.php.net/manual/ja/pdo.lobs.php

Recipe10: パノラマ写真でマイ・ストリートビューを実現

13年3月24日日曜日

Page 36: Gdg geo2

Recipe10: パノラマ写真でマイ・ストリートビューを実現

6:画像を合体(S)→PHPのGDなどのイメージ関数http://symfoware.blog68.fc2.com/blog-entry-910.html

7:画像のリサイズ(2048×1024)(S)GD http://b.n-at.me/archives/132

Webサービス http://www.image440.com/

JS http://b.n-at.me/archives/231 (おまけ)※画像処理系Webサービスまとめhttp://cg.xyamu.net/2d_links/entry143.html※全部HTML5でできるようになればいいのに・・・あるいはJSライブラリhttp://www.html5.jp/canvas/ref.html

8:画像の分割(256*256)縦8横4分割(S or Web)Webサービス http://picslice.com/

え?JSで?? http://today-only.net/img-shuffle/

9:StreetViewに適用   http://googlemaps.googlermania.com/google_maps_api_v3/ja/custom_streetview/3.html

13年3月24日日曜日

Page 37: Gdg geo2

え?今の機能ぜんぶAndroid4.2のカメラアプリに標準装備されている?ですって!w

Recipe10: パノラマ写真でマイ・ストリートビューを実現

6:画像を合体(S)→PHPのGDなどのイメージ関数http://symfoware.blog68.fc2.com/blog-entry-910.html

7:画像のリサイズ(2048×1024)(S)GD http://b.n-at.me/archives/132

Webサービス http://www.image440.com/

JS http://b.n-at.me/archives/231 (おまけ)※画像処理系Webサービスまとめhttp://cg.xyamu.net/2d_links/entry143.html※全部HTML5でできるようになればいいのに・・・あるいはJSライブラリhttp://www.html5.jp/canvas/ref.html

8:画像の分割(256*256)縦8横4分割(S or Web)Webサービス http://picslice.com/

え?JSで?? http://today-only.net/img-shuffle/

9:StreetViewに適用   http://googlemaps.googlermania.com/google_maps_api_v3/ja/custom_streetview/3.html

13年3月24日日曜日

Page 38: Gdg geo2

Menu����������●Geo系API紹介篇�〜プレーンな地図からトッピング感覚で作ってみよう〜

1. 現在地取得と地名検索(Geolocation�&�Geocoding)2. 地図と連動したストリートビューを表示(StreetView)3. 地図に道案内を表示(DirectionsAPI)4. �地図中のデータをカスタマイズ(StyledMap)

●Geo系API実践篇�〜�きっと役に立つ様々なTipsをご紹介〜5. ���様々なマーカー表示とパフォーマンスTips6. ���応用技で使いこなすStaticMapsAPI7. ���位置情報付きのURIを実装するメリット8. ���スマホ向けサイトをスマートに表示9. ���Canvasを使って画像ファイルをLocalStorageに記録 �10. ���パノラマ写真でマイストリートビューを実現

●Geo系API番外篇�����������・FirefoxOSを試す������������・MapsAPIの制限に関する誤解?!������������・0から1を生み出す為に

SampleCode: http://googlemaps.geo.jp/gdg2/

13年3月24日日曜日

Page 39: Gdg geo2

完成図 材料

・Firefox OS Simulator

・App manifest

作り方作り方インストール用のコードを追加してマニフェストファイルを設置

→アプリ vs Webサイト

    参考:http://www.openspc2.org/reibun/Firefox_OS/B2G/index.html

      (Firefox OS 使い方辞典)

 

Dessert: FirefoxOSを試す

13年3月24日日曜日

Page 40: Gdg geo2

1:GoogleMapsAPI Version2が終わっちゃうってホント?

2:有料化について�突然請求が来ちゃうの?�アクセス不能になるの?����

3:無料の範囲はどこまで?�これっていいの?ダメなの?

MapsAPIの制限に関するQ&A

13年3月24日日曜日

Page 41: Gdg geo2

1:GoogleMapsAPI Version2が終わっちゃうってホント?

2:有料化について�突然請求が来ちゃうの?�アクセス不能になるの?����

3:無料の範囲はどこまで?�これっていいの?ダメなの?

→2013/5/19がXday(ただしサポート終了から3年のポリシー適用の初事例であり実際にどうなるのかは?)

MapsAPIの制限に関するQ&A

13年3月24日日曜日

Page 42: Gdg geo2

1:GoogleMapsAPI Version2が終わっちゃうってホント?

2:有料化について�突然請求が来ちゃうの?�アクセス不能になるの?����

3:無料の範囲はどこまで?�これっていいの?ダメなの?

→制限を90日以上連続して超過した場合�������(25000回APIロード/日�(StyledMapやGeo系APIは2500回)

(StaticMapsは1000回/同一IP制限も)��むしろこの制限を突破する方が難しい数。心配するより逆にチャレンジすべき目標に!

→2013/5/19がXday(ただしサポート終了から3年のポリシー適用の初事例であり実際にどうなるのかは?)

MapsAPIの制限に関するQ&A

13年3月24日日曜日

Page 43: Gdg geo2

1:GoogleMapsAPI Version2が終わっちゃうってホント?

2:有料化について�突然請求が来ちゃうの?�アクセス不能になるの?����

3:無料の範囲はどこまで?�これっていいの?ダメなの?

→制限を90日以上連続して超過した場合�������(25000回APIロード/日�(StyledMapやGeo系APIは2500回)

(StaticMapsは1000回/同一IP制限も)��むしろこの制限を突破する方が難しい数。心配するより逆にチャレンジすべき目標に!

→誰でも無償で同じ機能が利用可能か・・・がポイント→フェアユースという考え方(Don’t be evil)

→2013/5/19がXday(ただしサポート終了から3年のポリシー適用の初事例であり実際にどうなるのかは?)

MapsAPIの制限に関するQ&A

13年3月24日日曜日

Page 44: Gdg geo2

0→1 ガレージ2人組から製品化へ 

Closing: 0から1を生み出すには

×3

×3

汎用化

製品化

※人月の神話 P5図1.1より

13年3月24日日曜日

Page 45: Gdg geo2

1→10 1製品から多くのファン獲得へ 

Closing: 1から10に育てるには

×30

×30

機能拡張ファン維持/獲得

運営費用/モチベーション

0→1

13年3月24日日曜日

Page 46: Gdg geo2

10→100 多くのファンから当たり前のサービスへ 

Closing: 10から100へのキャズム越え

×300

×300

スケール収益安定性

社会化

0→1

1→10

キャズムライン

13年3月24日日曜日

Page 47: Gdg geo2

THX a lot !!Let’s enjoy coding !(´ڡ`!)

13年3月24日日曜日