タグ: google map api

Google Maps APIメモ(v2) #6 オリジナルマーカー情報をjsonデータで読み込み

シリーズ第6弾、シリーズこれで終了
第5弾では、オリジナルマーカーは1種類1個だけだったのですが、今回はオリジナルマーカーを複数種類、複数個読み込んでみようかと。
しかも、それをjsonデータから読み込んで、ズームレベルでの表示/非表示の管理や、情報ウインドウの管理も一度にしちゃおうじゃないか。
というBlogに書くのがめんどくさくなった?反響がないことによる手抜き?みたいな感じです。

やることの整理

  • オリジナルアイコンは、第5弾で作った雪と、星の2種にする。
  • オリジナルアイコンの数は適当に複数個。
  • 任意のレベルでオリジナルアイコン出現
  • オリジナルアイコンをクリックするとそのアイコンの情報ウインドウが表示

参考にしたところ

サンプル

jsonデータ

用意したjsonデータは下記の通り

{
    "marker":[
    {
        "category": "star",
        "lat":75,
        "lng":10,
        "html":"オリジナルアイコンの一番星や〜!",
        "minZoom":1,
        "maxZoom":2
    },
    {
        "category": "star",
        "lat":-23,
        "lng":107,
        "html":"スターですが何か?",
        "minZoom":2,
        "maxZoom":3
    },
    {
        "category": "snow",
        "lat":60,
        "lng":60,
        "html":"オリジナルアイコンの初雪や〜!",
        "minZoom":2,
        "maxZoom":3
    },
    {
        "category": "snow",
        "lat":-64,
        "lng":18,
        "html":"きっと君は・・・",
        "minZoom":3,
        "maxZoom":3
    },
    {
        "category": "snow",
        "lat":-80,
        "lng":-117,
        "html":"降りますか?降られますか?",
        "minZoom":3,
        "maxZoom":3
    }
    ]
}

スクリプト

function createCustomTileLayer(){
    var dataLayer = new GTileLayer(new GCopyrightCollection(),0,3);
    //0,3はズームレベルの範囲
    dataLayer.getOpacity=CustomTileLayer_getOpacity;
    dataLayer.isPng=CustomTileLayer_isPng;
    dataLayer.getTileUrl=CustomTileLayer_getTileUrl;
    return dataLayer;
}
var CustomTileLayer_opacity = 1.0;
var CustomTileLayer_png = true;
var CustomTileLayer_getOpacity = function getOpacity() {
    return CustomTileLayer_opacity;
}

var CustomTileLayer_isPng = function getOpacity() {
    return CustomTileLayer_png;
}

var CustomTileLayer_getTileUrl = function(tile, zoom) {
    var x = tile.x;
    var y = tile.y;
    return "tiles/"+zoom+"/"+x+"_"+y+".png";
}

function createCustomProjection() {
    var myProjection = G_NORMAL_MAP.getProjection();
    myProjection.tileCheckRange = function (tile, zoom, tilesize) "
    return myProjection;
}

var map;
var manager;

function initialize(){
    if(GBrowserIsCompatible()){
        var mapCustom = new GMapType([createCustomTileLayer()],createCustomProjection(),"")
        map = new GMap2(document.getElementById("gMap"),{
            mapTypes:[mapCustom]
        });
        map.addControl(new GSmallMapControl());
        map.enableDoubleClickZoom();
        map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(0,0),1);

        manager = new GMarkerManager(map);
        GDownloadUrl("./data.json",createMap);
        
        //クリックされた場所の緯度、経度を表示
        GEvent.addListener(map, "click", function(marker, point) {
            document.getElementById("lat").innerHTML   = point.lat();
            document.getElementById("lng").innerHTML = point.lng();
        });
    }
}

function createMap(jsondata){
    var json = eval("(" + jsondata + ")");
    for (i=0;i<json.marker.length;i++){
        var category = json.marker[i].category;
        var lat = json.marker[i].lat;
        var lng = json.marker[i].lng;
        var html = json.marker[i].html;
        var minZoom = json.marker[i].minZoom;
        var maxZoom = json.marker[i].maxZoom;
        var marker = createMarker(category,lat,lng,html,minZoom,maxZoom);
        manager.addMarker(marker,minZoom,maxZoom);
        manager.refresh();
    }
}

var icon = Array();

icon["snow"] = new GIcon();
icon["snow"].image = "./icon/snow.png";
icon["snow"].shadow = "./icon/snow_s.png";
icon["snow"].iconSize = new GSize(20,20);
icon["snow"].shadowSize = new GSize(21,23);
icon["snow"].iconAnchor = new GPoint(10,10);
icon["snow"].infoWindowAnchor = new GPoint(10,10);

icon["star"] = new GIcon();
icon["star"].image = "./icon/star.png";
icon["star"].shadow = "./icon/star_s.png";
icon["star"].iconSize = new GSize(34,34);
icon["star"].shadowSize = new GSize(35,37);
icon["star"].iconAnchor = new GPoint(17,17);
icon["star"].infoWindowAnchor = new GPoint(17,17);

function createMarker(category,lat,lng,html){
    var point = new GLatLng(lat,lng);
    var marker = new GMarker(point,icon[category]);
    GEvent.addListener(marker, "click", function(){
        map.panTo(new GLatLng(lat,lng));
        marker.openInfoWindowHtml(html);
    });
    return marker;
}

あんまりイラスト汚すのも忍びないので、数も少なめで雰囲気も似せてますが、オリジナルアイコンには影を付けてるのでよく見るとわかると思います。
minZoomというのは、アイコンが出現するレベルで、maxZoomまでは、アイコン出てます。
それ以上のズームレベルになるとアイコン消えます。
1箇所どうにもできないところがあって、mixZoom(オリジナルアイコンが表示されるズームレベル)が1の場合が、ズームレベル0の時も表示されてしまうようです。
これは、バグなんだろうか?
このネタは、もともと「沢山の情報をうまく整理して、楽しげにイラストに落とし込めないか?」というのを解決するために、Google Maps API使ったらできるかな。ということで作ったのが基になってまして、それをメモしてました。
なんかもやもやして解決したいことあったらお気軽にご相談ください。

サンプル

スペシャルサンクス
Sampleで使用しているイラストは、高田さんに無理言って借りちゃいました。
ありがとうございます。
プロジェクト管理ツールBacklog(バックログ)の本体、告知サイトSubversionページのインターフェースデザインも高田さんです。
関連エントリー

Google Maps APIメモ(v2) #5 オリジナルのマーカーを追加する(まずは1種類1個だけ)

シリーズ第5弾
第4弾で作ったマップにオリジナルのマーカーを追加してみる。
まずは1種類1個だけ。

参考にしたところ

オリジナルマーカー画像の作成について

アイコンの前面画像とアイコンの影(必要ない場合はなくてもいいんだろうけども)を作成するんだけども、起点は左上なので、影を書き出す時も、そこを気にして書き出せばOK。
Fireworksの場合は、背景透明で作って、PNG32で書き出せばいいみたい。影のアルファ値も保ってくれているようです。

  • 前面画像のようす

スクリプト

function createCustomTileLayer(){
    var dataLayer = new GTileLayer(new GCopyrightCollection(),0,3);
    //0,3はズームレベルの範囲
    dataLayer.getOpacity=CustomTileLayer_getOpacity;
    dataLayer.isPng=CustomTileLayer_isPng;
    dataLayer.getTileUrl=CustomTileLayer_getTileUrl;
    return dataLayer;
}
var CustomTileLayer_opacity = 1.0;
var CustomTileLayer_png = true;
var CustomTileLayer_getOpacity = function getOpacity() {
    return CustomTileLayer_opacity;
}

var CustomTileLayer_isPng = function getOpacity() {
    return CustomTileLayer_png;
}

var CustomTileLayer_getTileUrl = function(tile, zoom) {
    var x = tile.x;
    var y = tile.y;
    return "tiles/"+zoom+"/"+x+"_"+y+".png";
}

function createCustomProjection() {
    var myProjection = G_NORMAL_MAP.getProjection();
    myProjection.tileCheckRange = function (tile, zoom, tilesize) {
        var mapsize = 256*Math.pow(2,zoom);
        if (tile.y < 0 || tile.y * tilesize >= mapsize) {
            return false;
        }
        if (tile.x < 0 || tile.x * tilesize >= mapsize) {
            return false;
        }
        return true;
    }
    return myProjection;
}

snowIcon = new GIcon();
snowIcon.image = "./icon/snow.png";
snowIcon.shadow = "./icon/snow_s.png";
snowIcon.iconSize = new GSize(20,20);
snowIcon.shadowSize = new GSize(21,23);
snowIcon.iconAnchor = new GPoint(10,10);
snowIcon.infoWindowAnchor = new GPoint(10,10);

function initialize(){
    if(GBrowserIsCompatible()){
        var mapCustom = new GMapType([createCustomTileLayer()],createCustomProjection(),"")
        var map = new GMap2(document.getElementById("gMap"),{
            mapTypes:[mapCustom]
        });
        map.addControl(new GSmallMapControl());
        map.enableDoubleClickZoom();
        map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(0,0),1);
        var html = "追加した雪だよ";
        var marker = new GMarker(new GLatLng(60,60),snowIcon);
        GEvent.addListener(marker, 'click', function() {
            marker.openInfoWindowHtml(html);
        });
        map.addOverlay(marker);
        //クリックされた場所の緯度、経度を表示
        GEvent.addListener(map, "click", function(marker, point) {
            document.getElementById("lat").innerHTML   = point.lat();
            document.getElementById("lng").innerHTML = point.lng();
        });
    }
}

右側の男の子の帽子の右上にオリジナルのアイコン置いてます。
マップを拡大縮小してもサイズが変わらないのがオリジナルのアイコンです。
通常、イラストのこの場所にアイコンを置きたい!とか決まっているはずなので、クリックしたらそこの緯度、経度を表示するようにしてます。
HTML側は、下記のようにしてます。

<div id="gMap"></div>
<ul>
<li>緯度(lat):<div id="lat"></div></li>
<li>経度(lng):<div id="lng"></div></li>
</ul>

サンプル

スペシャルサンクス
Sampleで使用しているイラストは、高田さんに無理言って借りちゃいました。
ありがとうございます。
プロジェクト管理ツールBacklog(バックログ)の本体、告知サイトSubversionページのインターフェースデザインも高田さんです。
関連エントリー

Google Maps APIメモ(v2) #4 オリジナルの画像をタイルレイヤーで表示

シリーズ第4弾
いつもは、地図とかで使っているGoogle MaGoogle Mps APIだけど、
使い方によっては、色んな事考えられるぞ。という例のメモ

オリジナルの画像や写真とかをGoogle MaGoogle Mps APIを使って表示できるようにする。

参考にしたところ

タイル画像の切り出しについて

タイル1枚は、256*256pxらしい。
FireBugで確認してみた画面↓

  • ズームレベル0でタイル1*1枚
  • ズームレベル1でタイル2*2枚
  • ズームレベル2でタイル4*4枚
  • ズームレベル3でタイル8*8枚

ということらしい。
じゃあ、横長や縦長の画像の場合は、どうなるんだ?とも思って実際に試してもみたが、
ズームレベル0だとやはりタイル1枚のみが表示される状態。
ということは、タイル画像を作成するときに、正方形にちょうど収まるように作ってやればいいみたい。
まずは、Sampleを見てみてください。

Fireworksでの作業手順メモ

  1. タイルの最大サイズを決めて、ファイル作成
    Sampleは、8*8枚、2048*2048pxとした。)
    丁度メモリの容量みたいな数字ですね。
  2. 最大サイズでスライスレイヤー(Webレイヤー)作る
  3. レイヤーフォルダ分けながら、半分のサイズにしながら、そのサイズの中でセンタリングする。
    ※レイヤーの名前は、ズームレベルと合わせとくと、わかりやすいかも。

    • ズームレベル3
    • ズームレベル2
    • ズームレベル1
    • ズームレベル0
  4. スクリプトで、
    "tiles/"+zoom+"/"+x+"_"+y+".png"とかで画像を読み込ますので、それに合わせて、画像を書き出す。
  5. いちいちFireworksのWebレイヤーに名前を付けるのがめんどうな時は、
    • 一度、Webレイヤーに名前を付けたファイルからコピペする
    • もしくはFireworks-ファイル-書き出しのオプションを変更して、Webレイヤーを削除しながら書き出す
      • Fireworks-ファイル-書き出しのオプション
      • 設定例

画像の切り出しをやってくれるツールもあるみたいです。

実際にオリジナルのマップを作成する場合には、文字を入れたりもするでしょうから、縮尺によって文字サイズを変更したい場合も出るはずです。
ちなみに、Sampleもクレジット表記部分は、ズームレベルによって大きさを変えている

スクリプト

function createCustomTileLayer(){
    var dataLayer = new GTileLayer(new GCopyrightCollection(),0,3);
    //0,3はズームレベルの範囲
    dataLayer.getOpacity=CustomTileLayer_getOpacity;
    dataLayer.isPng=CustomTileLayer_isPng;
    dataLayer.getTileUrl=CustomTileLayer_getTileUrl;
    return dataLayer;
}
var CustomTileLayer_opacity = 1.0;
var CustomTileLayer_png = true;
var CustomTileLayer_getOpacity = function getOpacity() {
    return CustomTileLayer_opacity;
}

var CustomTileLayer_isPng = function getOpacity() {
    return CustomTileLayer_png;
}

var CustomTileLayer_getTileUrl = function(tile, zoom) {
    var x = tile.x;
    var y = tile.y;
    return "tiles/"+zoom+"/"+x+"_"+y+".png";
}

function createCustomProjection() {
    var myProjection = G_NORMAL_MAP.getProjection();
    myProjection.tileCheckRange = function (tile, zoom, tilesize) {
        var mapsize = 256*Math.pow(2,zoom);
        if (tile.y < 0 || tile.y * tilesize >= mapsize) {
            return false;
        }
        if (tile.x < 0 || tile.x * tilesize >= mapsize) {
            return false;
        }
        return true;
    }
    return myProjection;
}


function initialize(){
    if(GBrowserIsCompatible()){
        var mapCustom = new GMapType([createCustomTileLayer()],createCustomProjection(),"")
        var map = new GMap2(document.getElementById("gMap"),{mapTypes:[mapCustom]});
        map.addControl(new GSmallMapControl());
        map.enableDoubleClickZoom();
        map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(0,0),1);
    }
}

サンプル

スペシャルサンクス
Sampleで使用しているイラストは、高田さんに無理言って借りちゃいました。
ありがとうございます。
プロジェクト管理ツールBacklog(バックログ)の本体、告知サイトSubversionページのインターフェースデザインも高田さんです。
関連エントリー

Google Maps APIメモ(v2) #3 マーカーがクリックされたら情報ウインドウを表示する

まだまだ基本的なシリーズ
マーカーがクリックされたら情報ウインドウを表示する

function initialize(){
    if(GBrowserIsCompatible()){
        var map = new GMap2(document.getElementById("gMap"));
        map.addControl(new GSmallMapControl());
        map.enableDoubleClickZoom();
        map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(33.590456,130.401793),13);//13はズームレベル
        var point = new GLatLng(33.584361,130.398607);
        var html = 'マーカーと<br />情報ウインドウの<br />テストですが何か?';
        marker = new GMarker(point);
        GEvent.addListener(marker, 'click', function() {
            marker.openInfoWindowHtml(html);
        });
        map.addOverlay(marker);
    }
}

サンプル

関連エントリー

Google Maps APIメモ(v2) #2 簡単コントローラーの追加

シリーズ第2弾

コントローラーの追加

地図へコントローラー追加

  • 地図へ小さいコントローラー追加
  • ダブルクリックでズーム
  • スクロールホイールでもズーム
function initialize(){
    if(GBrowserIsCompatible()){
        var map = new GMap2(document.getElementById("gMap"));
        map.addControl(new GSmallMapControl());
        map.enableDoubleClickZoom();
        map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(37.4419,-122.1419),13);
    }
}

サンプル

関連エントリー

Google Maps APIメモ(v2) #1 超基本

忘れまくってるのでメモ

超基本

head内にスクリプトを読み込む

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=上で取得したAPIキー"
    type="text/javascript"></script>
<script src="path-to-file/map.js" type="text/javascript"></script>

map.jsの中身

function initialize() {
    if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map_canvas_id"));
        map.setCenter(new GLatLng(37.4419, -122.1419), 13);
    }
}

bodyタグ

<body onload="initialize()" onunload="GUnload()">

HTMLの中身

<div id="map_canvas"></div>

という空のdivを用意する。幅と高さは指定してやる。
サンプル

関連エントリー