プロが教えるわが家の防犯対策術!

自分が持っているラスターの空間データをgoogle earth上に表示することを考えています。
例えば、地形標高のデータがあるとします。データのフォーマットは格子状であり、碁盤の目と同じ形式になっています(エクセルのシートと同じ形式)。地理情報としては、シートの左上端の緯度経度とか格子間の距離(x、y方向で一様)は取得できるという程度です(頑張ればもっと取得できますが)。これをKLM形式で保存すればgoogle earthが呼び出され、それを背景とした自分の情報が表示されるのではないかと思っています。また、格子状のデータが時間的に変動していくような場合、アニメができると思いますが、google earth上でそれを表示することも考えています。機能の名称がわかればその仕様を調べていくと何とかなるかなとは思いますが。例えば、単にjpgなどの画像を張り付ける場合は<GroundOverlay>を使うと思います。このような画像はラスターデータになると思いますがバイナリ形式ですね。テキスト形式のラスターファイルということになります。
また、このような方向性で解説されている書籍とか情報を取得する方法について教えて頂きたいのですが。方向性が違う場合は考え方がわかる文献等を教えて頂ければと思います。よろしくお願いします。

A 回答 (5件)

No4です。



おっとっと!!
ごめんなさい。勘違いしていたようです。m(__)m
私の回答はGoogle Earthがベースではなく、Google Mapsをベースにしたものでした。
(うっかり勘違い(汗))

とは言え、平面的に表示するのであれば、Mapでも写真表示と地図表示を切り替えられますので、結果的に似た表示を得ることが可能ではないかと思います。
参考までに、No3のサンプル実行時の画面を添付しておきます。
(縮小されるので、ぼやける可能性があります。
 No3そのままでは地図表示になりますが、写真表示に切り替えました)

慌てて、Google Earthの方を調べてみましたが、既にご存知のようにKMLデータの追加は可能なようです。
KMLは良く存じませんが、AnimatedUpdateなるタグも存在するみたいなので、何らかのアニメーションが可能なのかも知れません。
Google EarthのKMLドキュメンテーションは以下にあります。
https://developers.google.com/kml/documentation/ …

>前回ご照会いただいた方法はコピペした上で、ファイル名を
>拡張子htmlで保存してブラウザで実行するということでしょうか。
その通りです。(Google Mapsはブラウザ表示ですので)
ただし、No3でお断りしましたように、最近はkey登録しないとMap APIを利用できなくなってしまったようなので、そのままでは表示できません。
keyが必要になります。(開発者側のみ。閲覧者には不要)

No4で説明しましたように、Mapの場合はAPIが公開されていて、いろいろなことが自由にできるようになっています。
APIはjavascriptベースですので、javascriptの知識がないと難しいです。
javascriptはプログラミング言語なので、KML(=マークアップ言語)に比較すれば、自由度が高いと言えると思います。
一方で、できることはAPIの範囲に限定されているので、APIによるとも言えますが…
(APIにないことも不可能ではないと思いますが、途端に面倒で難しいことになります)

前にも言及しましたが、MapでもKMLの読込みは可能になっています。
KMLにしなくても、何らかの形式でメッシュデータに変換できれば、(javascriptがプログラム言語なので)地図上に表示することが可能です。(No3はKMLを利用していません)

私が勝手に勘違いしていましたので、No2、No3で挙げていたサイトはMapの方の解説サイトですが、Mapに関する入り口はこちらです。
https://cloud.google.com/maps-platform/?hl=ja
APIのドキュメントはこちら
https://developers.google.com/maps/documentation …
「GoogleEarthのKMLファイルで」の回答画像5
    • good
    • 0
この回答へのお礼

懇篤な回答ありがとうございます。このような技術はどのような方向で勉強していくのだろうと思っていました。APIというのは私の中では割と鬼門です。相手の仕様にあわせて自分を調整するという面があり、型にはまっていく必要があるように思いました。APIを使わない、となると自由ですが自分で何もかもやるということでそれはそれで厳しいように思います。やはりAPIでやる方向性を模索していきたいと思います。私はソースプログラムをはじめから書いて作成する(スクラッチする)という癖があり、そのために生産性が低くなってしまっています。Javascriptも魅力的なものだと思っています。単にhtmlの内部に書くものだと思っていましたが、未来的な言語だということです。

お礼日時:2018/09/22 02:23

No3です。



>何を参照していったらこの方向性を学ぶことができるのでしょうか。
方向性は、すでにご質問文にほぼ出ていると思います。(私は、最初は勘違いしましたが…)
『マップの表示に何らかのデータを重ねて表示したい。できればそれをアニメーションで変化させたい。』
ほとんどこれ(↑)に尽きていますので、後は、具体的にどう実現するかということになると思います。

google mapを利用する前提なので、HTMLでブラウザベースになるでしょうし、そこでいろいろな処理をしたいとなると、No2、3でもご紹介していますが、maps API(=javascript)を利用するのが便利だということになります。
google側でも、いろいろな想定をしてAPIを用意してくれていますので、できるだけそれにあるものをうまく利用する方が簡単になります。
(もちろん自前でやっても良いですが、面倒さが増えるだけだと思います)

・・・ということで、まずは、APIで用意されている内容をざっと眺めてみて、自分がやりたい内容に近そうなものを探してみます。(概ねNo2の回答内容です)
No3を試作するにあたっては、メッシュを表すのには矩形でいけそうだと考え、ユーザ側から色や透明度を任意に変更可能な仕様になっていることを確認して選定しました。
(まぁ、描きっぱなしで変更できなければ、都度、全部消去して新たに描くようなことになるでしょうけれど…)

実現できそうな方法が見えたので、後は、APIのドキュメンテーションを参照しながら作成してみた次第です。
実際には、多少の試行錯誤を行っています。例えば、
・メッシュの矩形を枠線ありで表示してみたところ、枠線がきれいな直線にならない。(地図を拡大表示してゆけば直線になりますが、大縮尺の場合、画面のピクセル計算の関係で微妙にずれるところがでる。)
・これを解消しようと、メッシュピッチより少し小さめの矩形を並べてみたりもしましたが、線(この場合は隙間ですが)は直線的になるものの、位置によって表示されたりされなかったりと却って汚くなってしまう。(隙間を大きくするか、地図を拡大すれば見えますが…)
みたいな点でしょうか。
距離100mを算出する計算も、内容としては中学か高校の数学程度なのですが、最初は間違えてしまい、100m角にならないとか…(笑)

>やはり2次元配列に値を割り当てるということと、その2次元配列の
>格子1つ1つに地理情報を割り当てるということなのかなと思いますが。
メッシュ1個に配列の要素一つを割り当てています。
平面を扱うので2次元配列が最初に思いつきますが、実際の処理を考えてみると一旦メッシュへの設定さえできてしまえば、あとはあまり2次元を気にする必要がなさそうでしたので、1次元配列にしてしまった方が処理が簡単になりそうなのが見えていることもあり、ちょっとだけ迷いました。(2重ループが1重ですむので)
結局は、「平面なのだから、やっぱり2次元だろう!」と思い直して、2次元配列にしましたけれど。
実際の処理自体は、メッシュ1個で考えれば、時間とともに「(何かのデータの)数値が変わり、それを色に変換(No3では透明度ですが)して、表示しなおす」ということを、数が増えるのと繰り返し行うだけですので、それほど複雑な処理ではないと言えます。

質問者様のデータがどのような形式で存在しているかや、それをどう変換するのが簡単そうか、あるいは最終的にどのように表示したいのかなどを総合的に考えながら、google側が用意してくれている方法とうまくマッチングさせるところがキーポイントなのかも知れません。
    • good
    • 0
この回答へのお礼

迅速な回答を頂き有難うございます。私にはまだ荷が重い感じがしてきました。maps APIというものがgoogle earthに用意されていて、それを使って作業を進めるということで、javascriptで書かれいるmaps APIというものの仕様に合わせるということなのでそのドキュメントが大事ということがわかりました。一番分かり方法はそれが解説されている書籍とか文献あるいはサイトを指定して頂くということなのですが。
また、前回ご照会いただいた方法はコピペした上で、ファイル名を拡張子htmlで保存してブラウザで実行するということでしょうか。
チャット状態ですみません。

お礼日時:2018/09/06 16:48

No2です。



その後、解決なさったのかどうか不明ですが・・・

少し時間がとれたので、メッシュデータの反映の方法を試してみました。
とは言っても、質問者様のデータがどのようなものなのか不明ですで、勝手にデータを作成しています。
『100×100mを1メッシュとして、度数を色の濃淡で表示する』という想定です。
アニメーションとのことなので、マップ上に100mメッシュで矩形を敷き並べておいて、時間経過に応じた度数を色に変換して表示するというものです。

具体的には、色は1色のみで濃淡(=opacity)を対応させているだけの単純なものにしています。
メッシュの矩形はpolygonのrectangleをそのまま利用して、適当な初期値を2か所に与えて、それが増加・拡散していく様子としてみました。
拡散にバラツキを持たせたかったのですが、結果的にはあまりバラつきませんでしたね(笑)

アニメーションは、「メッシュ全体の次の度数を計算」→「表示に反映」を繰り返すという方法で実現しています。(質問者様のケースでは、計算ではなくて次のデータ群と入れ替えれば良さそうな感じですが…)

地図の左下のstartボタンのクリックで始まりますが、最初しばらくはあまり変化が出ません。
しばらくすると、それなりに拡散・増加してゆ区様子が見られると思います。

google mapsのAPIをしばらく利用しなかったら、仕様が変わっていて、ついにkeyが無いと表示できなくなったようです。(私の旧いkeyは「期限切れ」として扱われました)
今回の確認のためだけなので、ずるしてkey無しで動作テストしましたが、表示するのにはkeyが必要です。
https://developers.google.com/maps/documentation …
また、スクリプトの実行に「async defer」を指定する場合は、実行順序が不定になるようですので、順序の制御が必要になりますからご注意ください。

以下がテスト内容のサンプルですが、コードは動作確認だけの為にダラダラと書きっ放しのもので、見せられるようなものではありません。
間違っても参考になどなさらぬように(笑)
(「この程度のことならできそうです」という検証のためのものと考えてください)

<!DOCTYPE HTML>
<html lang="ja">
<head><title>sample</title>

<script type="text/javascript" src="http://maps.google.com/maps/api/js?key=××××" charset="UTF-8"></script>
</head>
<body>

<div id="map" style="height:600px;"></div>
<div><input type="button" value="start" style="width:5em;" /></div>

<script type="text/javascript">
const latC = 35.685, lngC = 139.753;
const cellsNum = 50, cellSize = 100;

var cells = [], op = [], timerID, interval = 200;
for(var i=0; i<16; i++){ op[i] = i / 20; }
var map = initMap(document.getElementById("map"));
createCells();

// *** button contorols ***
document.querySelector("div input").addEventListener("click", function(e){
var f = this.value == "stop";
this.value = f?"restart":"stop";
if(f){
clearTimeout(timerID);
reset();
} else {
anim();
}
});

// *** functions ***
function rnd(n, c){ return Math.random() * n + (c?c:0); }
function setCells(f){ cells.forEach(function(c){ c.forEach(f); }); }
function reset(){ setCells(function(e){ e.val = 0; }); }
function disp(){ setCells(function(e){
e.elm.setOptions({ fillOpacity:op[e.val/10|0] });
});
}
function setStartVal(){
cells[cellsNum*rnd(0.2,0.5)|0][cellsNum*rnd(0.2,0.5)|0].val = 35;
cells[cellsNum*rnd(0.3,0.2)|0][cellsNum*rnd(0.3,0.2)|0].val = 15;
}

// *** animation ***
function anim(){
count = 200;
setStartVal();
setTimeout(function(){
nextTerm();
disp();
count--;
if(count>0){
timerID = setTimeout(arguments.callee, interval);
} else {
document.querySelector("div input").click();
}
}, 10)
}

// *** calc next term ***
function nextTerm(){
var r, c, v, vn;
for(r=0; r<cellsNum; r++){
for(c=0; c<cellsNum; c++){
var v = cells[r][c].val, vv = v * 0.8;
v += nf(r, c, vv) + nf(r, c, vv);
cells[r][c].nval = v>150?150:v;
}
}
setCells( function(e){ e.val = e.nval; } );
disp();
}

function nf(r, c, v){
var y = r + (rnd(6, -3)|0), x = c + (rnd(6, -3)|0);
var vt = (y>=0 && y<cellsNum && x>=0 && x<cellsNum)?cells[y][x].val:0;
return vt>v?(vt-v)*rnd(0.15):0;
}

// *** create & set cells ***
function createCells(){
var ER = 6378137, deg = 180 / Math.PI;
var latD = cellSize/ER * deg, lngD = latD / Math.cos(latC/deg);
var latS = latC - latD * cellsNum / 2;
var lngS = lngC - lngD * cellsNum / 2;
var r, c;
var opts = {
fillColor: "#FF0000", fillOpacity: 0,
strokeColor: "#FFFFFF", strokeOpacity: 0.1,
strokeWeight: 2, map: map
};

for(r=0; r<cellsNum; r++){
cells[r] = [];
for(c=0; c<cellsNum; c++){
cells[r][c] = { val:0, nval:0, elm:new google.maps.Rectangle(opts) };
cells[r][c].elm.setBounds({
north:latD * r + latS,
south:latD * (r + 1) + latS,
east: lngD * (c + 1) + lngS,
west: lngD * c + lngS
});
}
}
}

// *** initialize Map ***
function initMap(mapElm){
var opts = {
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(latC, lngC)
};
return new google.maps.Map(mapElm, opts);
}
</script>
</body>
</html>
    • good
    • 0
この回答へのお礼

懇篤な回答ありがとうございます。実はあきらめていました。全く手つかずだったのです。教えて頂いたコードを見ながら勉強したいと思いますが、何を参照していったらこの方向性を学ぶことができるのでしょうか。google earthのKMLファイルの編集方法の書いてある本を見ながらいろいろ検討していたのですが、用途が広いので1つ1つの説明が薄い感じがして浅く広くという感じでした。今回の希望はそれ比べてかなりピンポイントなのかなと思いました。教えて頂いたコードの解読はできませんが、やはり2次元配列に値を割り当てるということと、その2次元配列の格子1つ1つに地理情報を割り当てるということなのかなと思いますが。こういうことを学ぶ道筋の方向性について教えて頂ければと思います。

お礼日時:2018/09/06 12:26

No1です



なさりたいことは大体わかりました。
オリジナルマップを作るのではなく、google mapの地図の上に重ねて(別のデータを)表示したいということですね。

詳しいわけではありませんが、No1でも紹介しましたようにgoogle側で様々なレイヤを用意してくれていますので、質問者様の状況にあったものを選ぶのが宜しいかと思います。
お手元のデータがどのような形式なのかわかりませんが、マップ(あるいはブラウザ)が扱いやすい形式に変換して利用することになると思います。
しかしながら、どのような形式にするのが簡単なのかは私にはわかりません。

ラスターデータなら、画像形式にしてしまって、位置を合わせて重ねるのが簡単そうに思えます。
https://developers.google.com/maps/documentation …
https://developers.google.com/maps/documentation …

KMLなどを始めベクトル化ができるのなら、No1にも書きましたようにKML取り込みが用意されています。(No1に記載済)
一般的なポリゴンデータに変換できるのなら。
https://developers.google.com/maps/documentation …
https://developers.google.com/maps/documentation …

例示しているサイトは、googleのAPIのサンプルサイトですが、今回見ていてこんなものもあるのに気づきました。
◇heatmap
https://developers.google.com/maps/documentation …
◇Fusion Tables
https://developers.google.com/maps/documentation …
データ形式が一般的なものなのかどうかは知りませんが、雰囲気的にはheatmapの形式にデータを変換できるのなら利用でそうな気もしますが・・・?

すでに、お気付きのように、引用しているサンプルサイトの左側に様々なタイトルで例示がありますので、そのあたりをじっくり眺めてみれば、お手元のデータ形式に一番マッチしたものを選択できるのではないかと思います。


重ねるデータ形式と手段が決まれば、その形式で時系列毎のデータを用意しておいて、順に表示内容を変えることでアニメーション化は可能と思います。(データが重い場合は、スムーズでないこともあり得るので、工夫が必要になるかも知れませんが)
    • good
    • 0
この回答へのお礼

回答、有難うございます。このような方向性の勉強方法について教えていただければと思います。APIというのは聞くには聞きますが、何のことだろうというレベルです(DLLのようなものかなとか)。KMLの基本的な事項から勉強していく必要があるでしょうか。KMLを調べていたらXMLにも行きつき、さらにHTMLも関連しているようなのでそちらをやるのかなとも思うのですが、そういう調子ですから、収束せず発散してしまうのです。

お礼日時:2018/09/06 12:32

こんにちは



なさろうとしていることがイマイチわかりませんが、KML形式って結果的にはベクトルなはずと思いますので、ラスターではないように思いますが、どのようなデータが対象なのでしょうね・・・
とりあえず、ざっとググってみただけなので、以下はぴったりの情報というわけではありませんが、ご参考にでもなれば。


「google mapの表示の仕組みだけ利用して、地図そのものを置き換えてしまう」ようなことなら
https://developers.google.com/maps/documentation …
https://developers.google.com/maps/documentation …

ただし、もともとが地球を表示するためのものなのでメルカトル図法になっているので、注意が必要です。
(以下の、パズルで図形を上下に移動してみるとわかるかと)
https://developers.google.com/maps/documentation …

>単にjpgなどの画像を張り付ける場合は<GroundOverlay>を使うと思います。
とご質問文でもおっしゃっているので、こういうことではないのかな?


「mapにKLMデータを重ねて表示したい」というようなことなのでしょうか?
KLMデータに限っても良いのなら、読込みや表示に関してはすでにgoogleがサポートしてくれていますので、それを利用するのが一番簡単でしょう。
(以下の周辺にいろいろな情報があると思います)
https://developers.google.com/maps/documentation …

実際に試してみている方の記事
(↑精査していません:ググると他にもいろいろ出てくるはず)
https://maps.multisoup.co.jp/blog/1169/
    • good
    • 0
この回答へのお礼

回答ありがとうございます。基本、ベクターデータしか扱えないということになるのでしょうか。地球上のデータは基本的には球面上なので緯度経度座標というものが与えられるわけですが、近似的に平面座標と見た場合、碁盤の目と同じになりますね(小縮尺)。エクセルのシートのようなものです。縦100横100の格子点に値が割り当てられると、その値に応じて色を塗り分けると1つの絵になります。そのような感じのデータをgoogleearth上に張り付けるということです。例えば、洪水はある場所で起こってその水深のデータがエクセルのシートのようなデータになっており、それをgoogle earth上に重ねると実際の地図上に洪水の水深の分布がカラーとして表示されるというものです。しかもそれが動画になっていると洪水の動きが動的に表示されるということになります。そういうことが所望なのですが。いかがでしょうか。もしベクターデータでしか与えられないというのならば、それでもできなくはないです。例えば、緯度、経度、水深という点群がいっぱいあるという風に加工しなおすことは可能です。どのような方法にも対応はできますが、ひとまずどのような方法(作業の方向性とかタグ名とか)で作成するのかを教えて頂ければと思います。
よろしくお願いします。

お礼日時:2018/08/29 15:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!