携帯電話のサービスエリアって繋がるのが当然になってあまり気にしなくなっていたんだけど、イーモバイルはサービスエリアが都市部に限定されてるから、否が応でも気にしないと大変なことになる。
それで、イーモバイルのサイトにはEM モバイルブロードバンドサービスエリアとしてサービス提供地域が確認できるようになってるんだけど、Googleマップみたいにドラッグでスクロールできるわけでもなく、いまいちな使い勝手。
他にはPDFでもダウンロードできるようになってて、印刷するには丁度いいんだけど、サイト上で見られる提供地域よりも古い情報(2008年5月)となってるし、解像度がいまいち。
上の画像はサイトのPNG画像とPDFを比較してみた図。
そこで、サイトのPNG画像を取得してGoogle Earthにオーバーレイできればよくない?いいんじゃね!
ということで作ってみる。
イーモバイルの画像ファイルについての考察1
まず、重ね合わせる元となるPNG画像を取ってこないといけないんだけど、ファイル名の命名規則を調べて、効率的に取ってこないと駄目だよね。
イーモバイルサイトで表示サービスエリアの移動操作はJavaScriptを使ってるので、そのソースを見て、なんとなく動作を理解する。
どうやら、緯度・経度がファイル名に対応しているらしい。第一段階はこんな具合。
http://emobile.jp/area/area/map1/5236/5236.png
map1:ズーム(横幅)。map1は横幅160km。
5236:前の2桁が緯度の軸、後ろの2桁が経度の軸。んで、後から色々試してわかったんだけど、前の2桁は2/3でかけると緯度となり、後ろの2桁は100を足すと経度となる。
加えて画像ファイルの表示範囲は上下左右位置の画像ファイルと半分重なるようになっている。
画像が提供されないエリアについては、下のソースみたくJavaScriptでフラグが管理されてあるのでそれを読み取ってエクセルにマッピングしてみた。
var inflag; inflag = 1; if (Mesh_1_XX <= 21) { inflag = 1; } else if (Mesh_1_XX <= 25) { if (Mesh_1_YY >= 36 && Mesh_1_YY <= 38) { inflag = 0; }; } else if (Mesh_1_XX <= 27) { if (Mesh_1_YY >= 36 && Mesh_1_YY <= 40) { inflag = 0; (以下省略)
これで、第一段階のKMLはPHPで生成して完成。
<?php print '<?xml version="1.0" encoding="UTF-8"?>'."n"; print '<kml xmlns="http://earth.google.com/kml/2.2">'."n"; print '<Document>'."n"; print ' <name>emobile</name>'."n"; for($i=36;$i<=68;$i++){ for($j=22;$j<=45;$j++){ $inflag = 1; if ($j <= 21) { $inflag = 1; }elseif ($j <= 25) { if ($i >= 36 && $i <= 38) { $inflag = 0; }; }elseif ($j <= 27) { if ($i >= 36 && $i <= 40) { $inflag = 0; }; }elseif ($j <= 29) { if ($i >= 39 && $i <= 52) { $inflag = 0; }; }elseif ($j <= 30) { if ($i >= 42 && $i <= 52) { $inflag = 0; }; }elseif ($j <= 31) { if ($i >= 45 && $i <= 52) { $inflag = 0; }; }elseif ($j <= 35) { if ($i >= 49 && $i <= 54) { $inflag = 0; }; }elseif ($j <= 38) { if ($i >= 49 && $i <= 57) { $inflag = 0; }; }elseif ($j <= 39) { if ($i >= 49 && $i <= 64) { $inflag = 0; }; }elseif ($j <= 41) { if ($i >= 52 && $i <= 68) { $inflag = 0; }; }elseif ($j <= 42) { if ($i >= 58 && $i <= 68) { $inflag = 0; }; }elseif ($j <= 43) { if ($i >= 62 && $i <= 67) { $inflag = 0; }; }elseif ($j <= 45) { if ($i >= 64 && $i <= 66) { $inflag = 0; }; }; if($inflag){ continue; } print ' <GroundOverlay>'."n"; print ' <name>emobile</name>'."n"; print ' <Icon>'."n"; print ' <href>http://emobile.jp/area/area/map1/'.$i.$j.'/'.$i.$j.'.png</href>'."n"; print ' </Icon>'."n"; print ' <LatLonBox>'."n"; print ' <north>'.(($i+2)/3*2).'</north>'."n"; print ' <south>'.($i/3*2).'</south>'."n"; print ' <east>'.($j+2+100).'</east>'."n"; print ' <west>'.($j+100).'</west>'."n"; print ' </LatLonBox>'."n"; print ' </GroundOverlay>'."n"; } } print '</Document>'."n"; print '</kml>'."n"; ?>
イーモバイルの画像ファイルについての考察2
第一段階では解像度になっとくできないので、第二段階(横幅40km)を取ってくることにする。
http://emobile.jp/area/area/map2/5236/52364D.png
52364D:前の4桁については第一段階と同じ、後ろの2文字は第一段階のエリアを16分割した場所を示す。
上を北にした地図表現だと次のような場所。
3C | 3D | 4C | 4D |
3A | 3B | 4A | 4B |
1C | 1D | 2C | 2D |
1A | 1B | 2A | 2B |
これさえわかれば、あとは同じなので、KMLにしてGoogle Earthで表示してみる。
死亡。
オーバーレイの画像をインターネットから取得して読み込んでいき、沖縄から九州まで時間をかけながら徐々に埋まっていくんだけど、福岡が見えないうちに動作が重たくなって、しまいにはGoogle Earthが落ちた。
よく考えれば、4000枚ものPNG画像をダウンロードしながら表示させるなんて無理ありすぎです。ごめんなさい。
それならば画像を合成してやればok
何度も画像をダウンロードしてるようだとイーモバイルに怒られるので、一旦ローカルに保存してから、それをPHPで16枚を1枚の画像に合成。
あとは第一段階のKMLを修正(重ね合わせの範囲が違うので)して、ようやくやりたいことができた!
発展としては、サービス提供エリアを画像認識でトレース→ベクトルデータに変換→SWFに。
イーモバイルだけじゃなく他の3キャリアのサービス提供エリアも同じことをする(調べたところ、全キャリアで画像によるサービスエリア表示をしていたので可能)。
全キャリアの重ね合わせをトグルできるようにして、キャリアごとにサービスエリアを比較できるようになっちゃう!!!
需要あるのかわかんないけど、勉強がてら近いうちにやってみたい。