はてなダイアリーに移転することにしました。
http://d.hatena.ne.jp/u87/
コードとか見やすくなると思います。
ここの記事はまとめなおしたりして、むこうにも書く予定。
おせわになりました。
元ネタはここ↓
4-2:地図の中心に常に『十字マーク』を表示する - Google Maps 活用講座
でもここはversion 2なので、version 3向けに改造する必要がある。
と言ってもそう難しいものではなく、地図が移動したら十字マークを描画すると読み替えれば簡単です。
4-2:地図の中心に常に『十字マーク』を表示する - Google Maps 活用講座
こう書いてあるとおり、画像をマーカーに使って、移動するたびにその画像を地図中央に移動させている。
ただversion 3だとmapイベントにmoveがない。
Google Maps API version 3 リファレンス (Google Maps API Version3 日本語ドキュメント(非公式))
リファレンスを確認すると、dragがそれのようだ。
画像はそのままパクらせて頂きました。
まずはマーカーに使う画像の情報を定義します。
var image = new google.maps.MarkerImage(
'images/center.gif'
, new google.maps.Size(39, 39)
, new google.maps.Point(0,0)
, new google.maps.Point(19,19)
);
細かなプロパティはリファレンスを参照していただくとして、簡単に説明。
まずはURLを指定。相対で大丈夫らしい。
続くsizeはその画像のサイズ。
次はその画像の表示開始座標であるorigin。version 3では大きなサイズの画像も使用できるようになっている。なので、複数のアイコンをつなげた大きな画像を用意して、その画像のどこから開始するのかを記載する。これと上の画像サイズの指定で見せたい箇所を指定することができる。
anchorが判りにくくて困った。
表示する際に開始地点(指定された緯度経度)をどこにするか、ということだと解釈した。
デフォルトでは、アンカーはイメージの下辺 - 中央(幅 / 2, 高さ の座標値)。つまりマーカーは指定された LatLng の位置に配置されたときは、アンカーの定義されたピクセル値は指定されたLatLngの位置です。
Google Maps API version 3 リファレンス (Google Maps API Version3 日本語ドキュメント(非公式))
デフォルトのマーカーは画像の下辺の中央がその地点であることを考えると、そうなのかな?って。
なので、画像の中央をその地点にしたいのであれば、XもYもサイズの半分を指定すればいいということだと思ったけど(伝わる?)。
これでプロパティの設定が完了。
次にマーカー…というか、画像マーカーを設定する。
var centerIcon = new google.maps.Marker({
icon: image
});
とりあえずfunctionの外側に書いた。
でもってonload=""で読み込んでる初期化関数で、地図上にマークしてやる。
centerIcon.setMap(map);
centerIcon.setPosition(myLatLng);
setMap()とsetPosistion()はnewの中でやってもいいかな?
var centerIcon = new google.maps.Marker({
icon: image
, map: map
, position: myLatLng;
});
これでとりあえず中央に表示されるようになる。
まだイベントを追加してないので、最初に設定した場所から移動してくれない。
dragイベントを追加してやる。
google.maps.event.addListener(map, 'drag', function() {
drawMarker(map.getCenter());
});
ちなみにイベント処理後にも同じようにdrawMarker()を追加しないと、ドラッグが発生するまでマーカーを表示してくれない。
で、drawMarker()はこれだけ。
function drawMarker(centerLocation){
centerIcon.setPosition(centerLocation);
}
地図の中央を引数にして、その場所に移動させてやる。
…がしかし!
なんだろう、この重さは。
ドラッグしても一瞬、地図についていっちゃうのね。
メモリがグルグルしてるので、恐らく処理的に思いのかもしれない。
ソースを最適化してやる必要があるのかな?
JavaScriptはよー判らん。
元々別にブログを持っていたが、他の記事との兼ね合いでプログラミングやサーバ関連をここに持ってきた。
それはそれでいいんだけど、日本のブログサービスと比較すると、やっぱり不親切に感じることが多いbloggerである。それが放置してきた一因でもあるんだけど。
移転しようかなぁ?
ブックマークだけ使ってるはてなあたりに。
緯度経度から住所を取得する
サンプルはここにある。
http://code.google.com/intl/ja/apis/maps/documentation/v3/services.html#ReverseGeocoding
まずはGoogle Maps APIにおける、Geocoderのリクエスト方法から。
下記URLを見ると、プロパティの一覧がある。
GeocoderRequest
Google Maps API V3 Reference - Google Maps JavaScript API V3 - Google Code
住所や郵便番号から検索する場合は、addressプロパティに住所か郵便番号を入れてやる。
緯度経度から検索する場合は、latLngに緯度経度を入れてやる。
レスポンスは以下。
GeocoderResponse
Google Maps API V3 Reference - Google Maps JavaScript API V3 - Google Code
formatted_addressというのが、例えば「日本,愛知県名古屋市○○区○○N丁目NNN」のような形式の文字列。
テストは、クリックした箇所を地図の中心にしてマーカーを置くサンプルを下にしました。
http://code.google.com/intl/ja/apis/maps/documentation/v3/examples/event-arguments.html
クリックした箇所の緯度経度はイベントオブジェクトから簡単に取得できるので、そいつをGeocoderに入れてやるようにソースを修正すればいい。
ソースのイメージはこんなふう。
var geocoder = new google.maps.Geocoder();
geocoder.geocode({latLng: location}, function(results, status){
if(status == google.maps.GeocoderStatus.OK){
// 正常に処理ができた場合
} else {
// エラーの場合
}
});
レスポンスである配列resultsの構成はこうなっている。
{types[]: String,
formatted_address: String,
address_components[]: {
short_name: String,
long_name: String,
types[]: String
},
geometry: {
location: LatLng,
location_type: GeocoderLocationType,
viewport: LatLngBounds,
bounds: LatLngBounds?
}
}
まずはresults[].formatted_addressを表示してみる。
名古屋パルコの西館はこういうふうに取得できた
[0]日本, 愛知県名古屋市中区栄3丁目29?1
[1]〒460-8681
[2]〒460-8406
[3]〒460-8430
[4]〒460-8432
[5]〒460-8791
[6]日本, 愛知県名古屋市中区栄3丁目29
[7]日本, 愛知県名古屋市中区栄3丁目
[8]日本, 愛知県名古屋市中区栄
[9]日本, 愛知県名古屋市中区
※ただしクリックする箇所によって番地や郵便番号(の並び)は微妙に異なる。
名古屋パルコといえば、対になるのはナディアパークだよな?ってことでナディアパークはこちら。
[0]日本, 伊勢町通り
[1]〒460-8434
[2]〒460-8435
[3]〒460-8678
[4]〒460-8685
[5]〒460-8433
[6]〒460-8444
[7]〒460-8432
[8]〒460-8674
[9]〒460-8688
住所じゃなくて、通りの名前と郵便番号が取得できた。
名古屋ってことで、市役所はどうかと思って、調べてみると…
[0]〒460-8508
[1]〒460-8501
[2]〒460-8534
[3]〒460-8520
[4]〒460-8522
[5]〒460-8521
[6]〒460-8528
[7]〒460-8513
[8]〒460-8507
[9]〒460-8514
※これもクリックする箇所によって郵便番号の並びが変わったり、「日本,大津通」が出てくる。
こちらも郵便番号。
どういう違いがあるのだろう?
今度はresults[].address_components[]を確認する。
これにはshort_name、long_name、types[]の三つがあるので、それぞれ表示させる。
面倒なのでresults[0]だけを対象にする。
名古屋パルコ(西館)
---------------
[0]short name : 1
[0]long name : 1
[0]types[0] : sublocality
[0]types[1] : political
---------------
[1]short name : 29
[1]long name : 29
[1]types[0] : sublocality
[1]types[1] : political
---------------
[2]short name : 3丁目
[2]long name : 3丁目
[2]types[0] : sublocality
[2]types[1] : political
---------------
[3]short name : 栄
[3]long name : 栄
[3]types[0] : sublocality
[3]types[1] : political
---------------
[4]short name : 中区
[4]long name : 中区
[4]types[0] : locality
[4]types[1] : political
---------------
[5]short name : 名古屋市
[5]long name : 名古屋市
[5]types[0] : locality
[5]types[1] : political
---------------
[6]short name : 愛知県
[6]long name : 愛知県
[6]types[0] : administrative_area_level_1
[6]types[1] : political
---------------
[7]short name : JP
[7]long name : 日本
[7]types[0] : country
[7]types[1] : political
---------------
※勿論住所が短ければ、配列の数も少なくなる。
「愛知県名古屋市X区XXXN丁目NNN」で終われば、パルコの例よりも配列の要素がひとつ少なくなる。
ナディアパーク
---------------
[0]short name : 伊勢町通り
[0]long name : 伊勢町通り
[0]types[0] : route
---------------
[1]short name : JP
[1]long name : 日本
[1]types[0] : country
[1]types[1] : political
---------------
名古屋市役所
---------------
[0]short name : 460-8508
[0]long name : 460-8508
[0]types[0] : postal_code
---------------
[1]short name : JP
[1]long name : 日本
[1]types[0] : country
[1]types[1] : political
---------------
address_componentsの含まれるshort_nameとlong_nameについて、「日本」か「JP」の違いしかないようなので、日本ではあまり意味はないか。
typesにはその値の種別が入っていると思っていいのかな?
「日本」が「country」で、「愛知県」が「administrative_area_level_1」か。
…とここまで調べてて、日本語のリファレンスにがっちり載ってたことに気づいた。
http://sites.google.com/site/gmapsapi3/Home/services
折角なので、調べたことは残しておくことにする。
それによると、「administrative_area_level_2」「administrative_area_level_3」まであるようだけど、日本じゃ関係ない。
ただ、これらの結果とリファレンスを見る限り、Google Maps APIのGeocoderを使って緯度経度から住所を取るというのは考え物だと思った。
上の例のように、パルコならまだしも、ナディアパークや市役所のようなパターンになった場合、郵便番号だけだったり、近隣の通りの名前しか取れないパターンがあるんじゃ、判断に困るしなぁ。
例えば一つのresults[]にshort_nameかlong_nameが三つ以上であれば、それは(それなりの)住所を取得できていると判断するか?
いやはや、ハマった。
とりあえずGoogle Maps API v3のテストをしてて、時間があるのでCSSでテストページの見栄えを整えていたら…
その1 何故か、Google Chromeに値がPOSTされない!
ヴァージョンは4.0.249.89。
IEとFirefoxは問題なかったんだけど、何故かchromeだけ$_POSTが空。
で、フォームの値をalert()してやるとダイアログには値が出てくる。
<html>に「xmlns="http://www.w3.org/1999/xhtml"」が指定してあったんだけど(コピペしてきたヤツを元にしているので。僕だったら入れない)、これを削除したら正常に動いた。
「え? これが原因?」と思って「xmlns」を戻したら、正常に値が送られた。
原因はこれじゃないってこと??
ますます判らん。
その2 FirefoxにはinnerText()が使えない。
知るかよ!ってカンジだ。
それだけ。
忘れないようにメモ(とくにその2ね)。
その1は…なんだったんだろう??
指定した地点から、指定した距離(km)離れている施設の検索は出来るようになった。
機能的には不要だが、ルート表示をしてみようと思い、サンプルを参考にやってみた。
http://code.google.com/intl/ja/apis/maps/documentation/v3/examples/directions-simple.html
ただこれ、ルートだけじゃなくて、開始位置とゴールにマーカーを置くんだよね。
検索結果として表示している地図には、既にマーカーが置かれてる。だからいちいちAとBのマーカーが置かれると困るんだ。
まぁ、検索範囲の中央を示す地点には(いまのところ)なにも置いてないのでAのマーカーは我慢しようじゃないか。
しかし、ゴールのBのマーカーはいらん!
解決策はないものか?
郵便番号(三桁、四桁別々)と半径(キロメートル)を入力して、ボタンを押下すると、地図上に円を描くようにしてみる。
忘れないように、とりあえずfunctionだけ書いておく。
JavaScriptは始めたばかりなので、スマートかどうかは自信がない。
参考にしたのはここ。
Circle Object - Google Maps API V3 Reference - Google Maps JavaScript API V3 - Google Code
Maps API V3 Overlays (Google Maps API Version3 日本語ドキュメント(非公式))
Google Maps API V3 Demo Gallery - Google Maps JavaScript API V3 - Google Code
このページにリンクがはってるこのデモが一番参考になるのかな?
Circle Overlay
Drag the marker to move the circle
入力チェックをしてないので、注意すること。
一応、Version3で検証。
var map;
var circle;
// onloadは割愛
function drawCircle(){
// 我ながら値の取得方法については不細工だなぁと
var zip1 = document.getElementsByName('zip1')[0].value;
var zip2 = document.getElementsByName('zip2')[0].value;
var zipcode = zip1 + "-" + zip2;
// Circle Overlayのサンプルに3000kmを3000000と指定していた
// リファレンスを見たら、単位はメートルだったね
var radi = document.getElementsByName('radi')[0].value * 1000;
// 色の指定はテキトー
var circleColor = "#00AAFF";
// 指定された郵便番号から緯度経度を取得する
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: zipcode}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// 地図を移動させる
map.setCenter(results[0].geometry.location);
map.setZoom(10);
// 再描画の場合は、一旦前の円を消す
if(circle){
circle.setMap(null);
}
// 円の設定
circle = new google.maps.Circle({
fillColor: circleColor
, strokeWeight: 1
, radius: radi
, center: results[0].geometry.location
});
// 円の描画
circle.setMap(map);
} else {
alert(zipcode + ' not found');
}
});
}
new Circle()するところで、参考にしたデモのソースが「map: map」とかしてたんで何も考えずにそうやってたら、再描画が上手くいかなかった。
とりあえず指定した郵便番号を中心とした円を描いてくれる。新しく郵便番号を入れて実行すれば前のを消して、新しい円を描いてくれる…はず。
Labels
- apache (2)
- bash (1)
- CentOS (1)
- CPAN (2)
- CustomLog (1)
- Cygwin (5)
- C言語 (3)
- DBD::SQLite (1)
- DBI (1)
- gcc (1)
- Google Maps API (7)
- HTML (1)
- httpd.conf (1)
- iGoogle (1)
- Javascript (8)
- MySQL (4)
- Perl (1)
- PHP (11)
- PostgreSQL (1)
- sendmail (1)
- SetEnvIf (1)
- SQLite2 (1)
- Unix/Linux (16)
- vi (5)
- webalizer (1)
- Windows (13)
- xampp (1)
- yum (1)
- インストール (2)
- ケータイサイト (1)
- コマンド (2)
- シェルスクリプト (2)
- バッチファイル (3)
- フリーソフト (3)
- メール (2)
- レジストリ (1)
- 愚痴 (4)
- 日本語化 (6)
- 文字化け (3)
- 本 (1)