Gmaps ちょっぴり応用編 —複数のXMLを切り替える—

/web/javascript

Note: この記事は、3年以上前に書かれています。Webの進化は速い!情報の正確性は自己責任で判断してください。

Google Maps に関するdaiさんの質問、その2。

一つのgooglemap上で、複数のxmlを読み込み、例えば、京都スポットマップリンクを押すと、京都スポットマップxmlを読み込み、googlemap上に表示したり・・・ってのがやりたいですが・・・これは、色々と勉強して、なんとか出来そうなんですが・・・どうもコードが汚くてもっさりしてしまいます。そこで、Sigさんならどういう風に、されるのかな?っと思い、ご質問させて頂きました。

—Google Maps API Documentaion サクっと基本部分だけ, daiさんのコメント

Oui, monsieur... これはXMLを読み込む処理を onclick イベントに対応させれば良いので理屈としては簡単です。ただし、ただ読み込むだけではマーカー(とその他のデータ)が重複してどんどん重くなっていくので、その都度初期化してやる必要がありますね。

  1. map.clearOverlays();
  2. sidebar.innerHTML = "";
  3. gmarkers = [];
  4. htmls = [];
  5. i = 0;

...とまあ、こんな感じでXMLを切り替える度に初期化してやる訳です。
このなかで「clearOverlays()」がGmap上のマーカー類を一掃するメソッド。ドキュメントはここら辺。似た処理に「removeOverlay()」てのもあって、こっちは個別削除用。最初は for文+removeOverlay() で一個ずつ消してたんだけど、clearOverlays()で一括削除しちゃったほうが軽いみたいでした。

サンプルを以下に設置しておきます。前回の反省を元に、今回のはスクリプト部分をコピペすれば外部JS化できるようにしてありまっす。

だいぶコツを掴んできた。もう2~3個つくればライブラリ化できるかもしれない!

関連記事

Note: スパム対策が面倒なので、コメント投稿を廃止しました。以前のコメントは残します。
ご意見・ご要望はtwitter@sigwygかはてブコメントにて。

18 Comments

dai wrote:
あの~仕事速すぎますw
有難うございます!私のしたい事全て網羅していただいた上に、解りやすいご説明有難うございます!
勉強させて頂きます!

Sigさんにお聞きしたいのですが、私はある程度、サイト作成できるのですが、javascriptに関しては、全く持ってわかりませんってか、今まで見てみぬ振りをしてました。しか~し!

お忙しいのに、Sigさんのご対応に感激し、ここらで一つ、真剣に言語を勉強したいと思います!勝手にw
なので、よければ、javascriptを勉強するのに、良いサイトや本当あれば、お教えいただけませんか?

毎回、稚拙な質問ばかりしていては、心苦しいので、なんとか質問するにしても、手を煩わせることなく、質問できるレベルになりたいって思ってます。勝手にw
またお忙しいときで、結構ですので、ほなこれなんかエエンちゃう?ってのがあれば、お願いいたします。
アホかー男は、自分で発見するもんだ!なんて、事であれば、紳士に受け止めますw

しかし、凄いな~私はサイト作成は出来るのですが、プログラミング言語はわからないので、趣味程度だったんですが、今後
Sigさんのさらっと、やってしまうカッコよさに感銘され、本格的にはまりそうですw

また寄せていただきます~有難うございます! 2007–11–01 23:38
Sig. wrote:
喜んでもらえて良かったです^^
Sig.もま~プログラミングに関しては始めたばかりなんですが、最近ようやく自分で書けるようになってきて、ちょうど楽しくなってきた感じです。やっぱ自分で考えたものがちゃんと動いて、しかも人に使ってもらえたりなんかした日には、最高ですね!

おススメのサイトとかは... 実は無いです^^;
情報源として有用な所は幾つか購読してますが、How toって感じじゃないです。本にしてもWebサイトにしても、ただ読むだけでは「ふ~ん」で終わりですから、やっぱ初めは「こういうのが欲しい」「作りたい」てとこから作りながら調べるのが一番です。これは実感として。なのでGoogle先生ですかね? 調べたことは纏めとかないと忘れちゃいますから、Winだとメモ帳が便利だったり。

そんな感じで判らないことを調べ探していると、自然とドキュメントは増えていくものです。メモ用にdel.icio.usや「はてな」なんかのSBMを勧めておきます。ただ、「JavaScriptで何ができるのか」を知っていることは大きいと思うので、youmosさんやphpspotさんみたいなサイトを定期的に見ておくと良いでしょう。ちょっと上級になるとAjaxianとかが良いです。多くの利用例に触れておけば、次第にインスピレーションも湧いてくると思います。

HTMLとCSSをがっちり理解しておけば、DOMから入るのが楽しいですよ~。
表示/非表示なんかのCSS切替あたりが基本かと。

ちなみにiQueryなんかのライブラリの分析はとても勉強になりますが、ライブラリを使うことはあまり勉強には向いてないと思います。モノによっては違う言語のように使えることを目的としているものもありますので、変な癖が付いちゃうかもです。実務においては速いし信頼できるので積極的に利用すべきですが、ライブラリから入って実力が付くかどうかは疑問ですね。

あるていど自分で書けるようになってきたら、オライリー(通称サイ本: JavaScript 第5版)で基礎をがっつり。ここで霞が晴れたかのように理解できるようになってきます。Sig.はいまココ。そろそろ何か面白いものが作れるかもしれない...!

そんな感じで...って長いw 2007–11–07 14:26
サクライ wrote:
Sigさま。
大変素晴らしいプログラムをありがとうございます。参考にさせていただいております。

おかげさまで、複数のXMLを効率よく読みだすことができております。

たとえば、任意の複数のXMLデータを、1つのGoogleMAP上に読みだすことはできるのでしょうか。
map.clearOverlays();を無くせば、リンクを押して行くたびにマーカーは増えますし、
sidebar.innerHTML = "";を無くせば、サイドバーにも表示が増えてゆきます。
ですが、これだとクリックするたびに、際限なく増えていってしまいます。

1つのリンクを押しただけで、2つのXMLを読み込んで表示してくれるようにするのは無理なのでしょうか。
お店+金沢自然公園コース
などのようにHTMLでおこなうと、最初の1回はきちんと両方のXMLから情報を持ってきて表示してくれるのですが、2回目以降は、後ろのデータしか表示してくれなくなってしまいます。

なにか良い案はございますでしょうか。

お忙しいと存じ、恐縮ではございますが、お知恵を拝借願えればと思い書き込ませていただきました。 2007–11–07 17:44
Sig. wrote:
サクライさん、こんにちわ。
サクライさんも気付いている通り、初期化処理を取っ払えば複数のXMLデータを表示させている状態にはなります。つまり、単純に初期化処理を取っ払えばマップがリロード以外ではリセットされないため、リンクをクリックするたびにマーカーが際限なく増えていく状態になりますね。そうならないためには、初期化処理は必要。つまりここで重要なのは、初期化のタイミングってことです。新しいサンプルを用意しました。

> http://archiva.jp/test/set/gmaps_sample/xml_change2.html

変更点は、関数loadXML()から初期化処理の部分を関数init()として分離しただけです。onclickイベントの発生時に手動で初期化を行うことで、マーカーをリセットするタイミングをコントロールしています。HTML側の記述が多少長くなりますが、関数init()を実行しない限りはマーカーが消えないため、必要な数だけ関数loadXML()を実行すれば良い感じです。

もうちょい工夫すれば、もっと速くなりそうですけど... 考え方としてはこんな感じかな。
どないでしょ? 2007–11–08 02:13
サクライ wrote:
早速のお返事ありがとうございます。
http://www.ayadesign.biz/googlemap.html
やってみました。IEの場合、キャッシュが悪さをするようです。
上記URLでは、onlodeで「map_kanazawa.xml、map_tomioka.xml、map_example0.xml」の3つのファイルを読み込んでいます。そして、「すべてを表示」をクリックし時には、「map_ex1.xml、map_example2.xml、map_example1.xml、map_example0.xml、map_tomioka.xml、map_kanazawa.xml」を読み込んでいます。ですが、実際には、既に読み込んでいる3つのファイルは読み込まずに、残りの「map_ex1.xml、map_example2.xml、map_example1.xml」だけを読み込んでしまうようです。
ですから、一番最後に読み込むファイルが「map_example1.xml」となってしまい、表示順序が読み込みたい順番ではなくなってしまいます。
ただ、2回目以降に「すべてを表示」をクリックした場合は、キャッシュではなく読み直すのか、再度キャッシュを並び替えるのか、onclickに書いた順番道理に読み込まれて表示されます。もちろん、init();は記述してありますが、ブラウザがキャッシュを使ってしまうようです。

では、うまくいきませんでした。

表示時に複数のXMLをonlodeで読み込んで、さらに別の複数XMLをonclickで読み込む場合でも、IEですと同様にキャッシュによる並び替え不備がおこります。今回は、すべてを表示の読み込みファイルに「?all」と引数をつけて解決させました。 2007–11–08 17:14
サクライ wrote:
先ほどの記述で「では、うまくいきませんでした。」の部分。タグを書いてしまい消されてしまいました。不覚。。
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
では、うまくいきませんでした。
としたかった。 2007–11–08 17:19
Sig. wrote:
おぉ、けっこう本格的ですね!
さて、この問題... Sig.もすっかり忘れていたんですが、XMLHttpRequestにてデータを取得する際にGETメソッドだとキャッシュされます。原因はコレですね。解決策は3つ。

1.POSTメソッドを使用する
2.取得先のURLにユニークID(?hoge=hogehogeなど)を付加する
3.If-Modified-Sinceヘッダを付与する

サクライさんは2.の方法で解決したようですね。参考までに3.の方法を出しておきましょう。サンプルの104行目あたりで...

request.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
request.open("GET", filename, true);

...終了! 2007–11–08 20:53
Sig. wrote:
ちなみに「2.取得先のURLにユニークIDを付加する」は「毎回違うURLにする」と同義です。パラメータ付けて違うURLにしちゃえば、読み込むファイルは同じでもキャッシュ使わずに再読込してくれます。なのでgetTime()なんかと併用しても良いかもしらん。

「If-Modified-Since」は対象コンテンツの更新時刻をチェックさせる指定。指定した時間より後に更新されてれば新しく読み込みまっす。 2007–11–08 21:14
サクライ wrote:
Sig.さま。ありがとうございます。
「request.open」のあとに「request.setRequestHeader」は入れないと駄目なようでした。
ですが、ありがとうございます。これで、いちいち指定しなくてもいいわけですね。
http://www.ayadesign.biz/googlemap2/
それにしてもGoogleMapは、色々な機能がありますね。
タブを2つ以上にしたり、面を塗ったり、線を引いたり。

Sig.さまのおかげで、思い通りの物が作れそうです。
ありがとうございました。 2007–11–11 13:08
Sig. wrote:
ありゃ、逆でしたか。どうも詰めが甘いな~...orz
しかし、お役に立てたようで良かったです。
お互い頑張りましょ~! 2007–11–12 00:41
さんちゃん wrote:
Sig 様

私のやりたかった XMLのプログラムありがとうございます。
 防災Mapとして使用させて頂いています。

しかし 防災マップも 個人的な閲覧にも使用したくって(個人情報の入った(住所・氏名)MsAccessのActiveXで表示したいと思っています。 

現在は、氏名を除いた住所と lat・lng のXMLをWebサイトにアップしてHtmlに表示しています。

このXMLファイルを ローカルディスクに置いて読みこなせるにはどうすれば良いのでしょうか?

function loadXML(filename){   の後に

var request = new ActiveXObject('Microsoft.XMLDOM');
request.async = true;

を入れたり いろいろ試しましたが Javaが分からない私にとって ・・・ かなり苦戦しています。

よろしくお願いいたします。 2009–07–10 18:01
Sig. wrote:
俺もJavaは解りませんw ...と細かい突っ込みは置いといて、
Accessに関しては知りませんが、
ActiveXで使うならIE専用になると思いますよ。
いちおFxでもIETab入れれば動いた筈ですが。

ただ、まーIE6以下はXHRに対応していないので
いわゆるAjaxな処理はもともとActiveXを使っています。
IEで動かなかったとしたら、別の要因かなー、と。
ローカルのXMLを読み込む、というだけならサンプルのままでも全く問題ない筈です。
エラー内容が解らないことには何とも言えませんね。

いちおXHRの中身はこうなってますよー、という記事が↓
http://archiva.jp/web/javascript/XNLHttpRequest.html 2009–07–15 15:11
さんちゃん wrote:
Sig. さん
  ありがとうございます。

1 IEは v6 v7 v8 全てで試しました。

2 >別の要因かなー、と。

   インターネットオプションの設定も色々調べて最善策をとりましたが、XMLの読み込みはできませんでした。

3 >エラー内容が解らないことには何とも言えませんね。

  alert(request.readyState)
  を入れてみると  2 : 読み込み完了 をスルーします。(1・3・4)
   そのため  
    var markers = xmlDoc.documentElement.getElementsByTagName("marker");
  にエラーがかかります。(読み込まれていないのですね)

4 var request = new ActiveXObject('Microsoft.XMLDOM');
  request.async = true;
   を当ててやり filename を "xml_change1.xml" と固定し XMLを load() したら ローカルのファイルを
  読み込みました。
  ただし これだと複数のXMLの切り替えができません・・・・? よね?


今日までに色々とテストを繰り返したりサイト検索をした経過(粗末な頭で考えた私の推理)ですが、
 1 XMLはその名前が変数だと、ローカルからは開かないのでは?
 2 GXmlHttp httpはwebサーバが吐き出す物みたいで ローカルに吐き出すように頼んでも聞いてもらえない?
 
 んな感じですがいかがでしょう?


 >ローカルのXMLを読み込む、というだけならサンプルのままでも全く問題ない筈です。

 心強いお言葉で・・・頑張ってみます。 2009–07–16 17:57
Sig. wrote:
ごめんなさい。てきとー言いました。
サンプルのままだと、IEでのみローカルで表示されませんね。
ということで、以下のようにしてできました。

var url = filename;
var request = new ActiveXObject('Microsoft.XMLDOM');
request.async = true;

request.onreadystatechange = function() {
if (request.readyState == 4) {
var markers = request.documentElement.getElementsByTagName("marker");
...goodness...
}
}
request.load(url);


完了時に読み込んだXMLドキュメントのルートは、インスタンスの documentElement にセットされるようですねー。
ローカルのXMLを読み込むだけなら、これでできます。
AccessやActiveXの機能が絡んでくると、僕には答えられませんが! 2009–07–17 02:01
さんちゃん wrote:
Sig さん

 ありがとうございます。
えーっっっ 2:00までやってくださったんですか?

本当に 感謝 感謝 です。

私が、自分で作ってもいないのに、XMLが読み込まれた時には、大感激です。

AccessのActiveXにも取り込めるようになりました。
 これで個人情報をWebにアップしないで安心してGoogleMapで閲覧できます。

ついでに   ...goodness...   も頂きます。  ナイスです。

本当にありがとうございました。 2009–07–17 10:13
ぽりん wrote:
はじめまして。

xmlをマップに取り込むという基礎的なものはできたのですが
このサンプルのような応用だと自分には難しくてなかなかうまくいきません。


サンプル1のxmlファイルのテキストを一部載せていただくことはできないでしょうか?
お願いいたします。 2010–01–26 17:50
ぽりん wrote:
サーバーにxmlをあげるわけですから
webで入力すれば表示されますよね・・・

変な事を書いてしまってすいませんでした。


記事、勉強の役に立ってます! 2010–01–26 18:43
とみー wrote:
こんにちは。情報を探していたところたどり着きました!
質問なのですがxmlではなくjson形式で同様の事をしたいのですがどのように変換したらいいでしょうか?
jsonを吐き出すのはmap.phpで選択リンクでは1や2等の整数を入れmap.php?area=1というファイル名にさせたいです。

ちなみにjsonデータの取得は下記のようにしています。

GDownloadUrl(filename, function(doc, stat)
{

eval("loaddata=" + doc);


for (var i = 0; i < loaddata.data.length; i++) {
var marker = makeMarker(
loaddata.data[i].lat,
loaddata.data[i].lng,
loaddata.data[i].name,
loaddata.data[i].addr,
loaddata.data[i].link
);
}
}); 2010–04–14 12:05