2008/07/31

Slippy Mapを表示してみる

OpenStreetMapではサイトに表示しているメインの地図をSlippy Mapと呼んでいます。

最近、日本語サイトのOpenStreetMap Japan地図ページの改良をなさっている方が居て、私もちょっと触ってみたくなってBloggerに表示させてみることにしました。


ベースにしたのは、MediaWiki用のSlippy Map MediaWiki Extensionからの出力です。

サーバーからタイル(細分化された地図画像)を引っ張ってくることは直ぐにできましたが、タイル同士の間に数ピクセルの隙間が空いてしまいます。OSM.orgやOSM.jpで使用しているコードを覗いて見たり、OpenLayersの文書やソースを読んでみても解決できず二日程悩んでいました。ふと思い立ってFirefoxのアドオンのページを確認してみるとFirebugのFirefox3対応版が出ていたので早速インストール。HTMLを調査すると適用されているスタイル (padding:4px;) や要素のクラス名 (olTileImage) が簡単に分かり、直ぐに解決。この程度のことだから、OpenLayersのFAQやメーリングにも質問が出ていなかったんだと思いました。それにしてもFirebugは便利だなぁ。あまり使ったことがないので、使い方も良く分かんないけど...

やろうと思ったけどやり方が分からず、とりあえず現時点では諦めたこと。
  • 地図のスクロール時やズーム時に、OSM.orgの地図へのURLに入っている座標やズームレベルを更新すること。
    • URLのベースをOSM.orgサーバーへ向ける。
    • 座標の形式を lat=35.67255 lon=139.76183 のように普段GPSなどで見ているものと同じにする。
    • リンクテキストを Permalink 以外のものにする
  • ズームレベルに合わせたスケールを表示する。
これからやろうと思っていること。



上の地図を表示させているコードはこちら。( "+ expand source" のリンクをクリックして下さい。)
<style>
.map img { padding: 0px !important; border: none !important;}
</style>

<div class="map" style="margin-bottom:-35px;">

<!-- define a DIV into which the map will appear -->
<div style="width:400px; height:350px; border-style:solid; border-width:1px; border-color:#000;" id="map"></div>

<br/>
<span style="font-size:70%; background-color:white; position:relative;top:-65px;left:5px;z-index:1003;">Data by <a href="http://www.openstreetmap.org/?lat=36&lon=139&zoom=4" title="See this map on OpenStreetMap.org">OpenStreetMap</a><br/>
<a href="http://creativecommons.org/licenses/by-sa/2.0/" title="Creative Commons Attribution-Share Alike 2.0">CC-BY-SA-2.0</a></span>

</div>

<!-- bring in the OpenLayers javascript library -->
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<!-- bring in the OpenStreetMap OpenLayers layers. Using this hosted file will make sure we are kept up to date with any necessary changes. --> 
<script src="http://openstreetmap.org/openlayers/OpenStreetMap.js"></script> 

<script type="text/javascript"> 
var lon=139; 
var lat=36; 
var zoom=4; 
var map; 

function lonLatToMercator(ll) {
  var lon = ll.lon * 20037508.34 / 180;
  var lat = Math.log (Math.tan ((90 + ll.lat) * Math.PI / 360)) / (Math.PI / 180);
  lat = lat * 20037508.34 / 180;
  return new OpenLayers.LonLat(lon, lat);
}

window.onload=init; 

function init() {
  map = new OpenLayers.Map("map", {
    controls:[
      new OpenLayers.Control.Navigation(),
      new OpenLayers.Control.PanZoom(),
      new OpenLayers.Control.LayerSwitcher()],
    maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
    maxResolution:156543.0399,
    units:'meters',
    projection: "EPSG:900913"
  } );
  var mapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
  map.addLayer(mapnik);
  var osmarender = new OpenLayers.Layer.OSM.Osmarender("Osmarender");
  map.addLayer(osmarender);
  var cyclemap = new OpenLayers.Layer.OSM.CycleMap("Cycle Map");
  map.addLayer(cyclemap);
  var maplint = new OpenLayers.Layer.OSM.Maplint("Maplint");
  map.addLayer(maplint);
  var lonLat = lonLatToMercator(new OpenLayers.LonLat(lon, lat));
  map.setCenter (lonLat, zoom);
} 
</script>


追記

Widget追加ボタンを作成しました。
尚、上のコードで表示できるSlippy Mapは1ページに1つだけで、Widgetでは複数のSlippy Mapを同じページに表示できます。また、上のコードによるSlippy Mapと同じページ内にWidgetによるSlippy Mapがあると、その影響により指定した座標・ズームで表示できないことがあるようです。

2008/07/28

HaloScanでトラックバック

クリボウの Blogger Tipsを読んで、HaloScanのトラックバック機能を付けてみました。


HaloScanのアカウント作成後、ログインし直してInstallation Instructionsの画面に入ると、まず使っているブログの種類を選択します。自分の場合は Blogger or Blogspot (New Version / Google Login) なので、それを選択して手順通りにやってみましたが、HaloScan側で更新したテンプレートをBloggerにアップロードするところでエラーになり上手く行きませんでした。試しに、Blogger or Blogspot (Old Version)None of the Above / Manual を選択して、それらの手順もやってみましたが、別のエラーで上手く行きませんでした。

で、結局、Bloggerの [レイアウト] → [HTMLの編集] → 「テンプレートを編集」で「ウィジットのテンプレートを展開」にチェックを付け、エディタで開いた最初のHaloScan側で更新したテンプレートと睨めっこをしながら手作業で更新部分を編集してみたところ、やっと動くようになりました。

更新部分は3箇所で、今は下のようになっています。(HaloScan側で削除された部分はコメント化してあります。)

<!-- START comment out for haloscan (part 1)
            <a class='comment-link' expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><b:if cond='data:post.numComments == 1'>1 <data:top.commentLabel/><b:else/><data:post.numComments/> <data:top.commentLabelPlural/></b:if></a>
END comment out for haloscan (part 1) -->
<!-- start haloscan (part 1) -->
            <script src='http://www.haloscan.com/load/tatata7' type='text/javascript'> </script>
<span class='post-comment-link'>
<a class='comment-link' expr:href='"http://www.haloscan.com/comments/tatata7/" + data:post.id + "/"' expr:onclick='"HaloScan(" + "\""+ data:post.id + "\"" + ");return false;"'>
<script type='text/javascript'>postCount('<data:post.id/>');</script>
</a> | 
<a class='comment-link' expr:href='"http://www.haloscan.com/tb/tatata7/" + data:post.id + "/"' expr:onclick='"HaloScanTB(" + "\""+ data:post.id + "\"" + ");return false;"'>
<script type='text/javascript'>postCountTB('<data:post.id/>');</script>
</a>
</span>
<!-- end haloscan -->

<!-- START comment out for haloscan (part 3) 
     <a class='feed-link' expr:href='data:f.url' expr:type='data:f.mimeType' target='_blank'><data:f.name/> (<data:f.feedType/>)</a>
END comment out for haloscan (part 3) -->
<!-- start haloscan (part 3) -->
     <a class='feed-link' href='http://www.haloscan.com/members/rss.php?user=tatata7' target='_blank'>Comment Feed (RSS)</a>
<!-- end haloscan -->

<!-- START comment out for haloscan (part 2 - post) 
      <h4>
        <b:if cond='data:post.numComments == 1'>
          1 <data:commentLabel/>:
        <b:else/>
          <data:post.numComments/> <data:commentLabelPlural/>:
        </b:if>
      </h4>

      <b:if cond='data:post.commentPagingRequired'>
        <span class='paging-control-container'>
          <a expr:class='data:post.oldLinkClass' expr:href='data:post.oldestLinkUrl'><data:post.oldestLinkText/></a>
           
          <a expr:class='data:post.oldLinkClass' expr:href='data:post.olderLinkUrl'><data:post.olderLinkText/></a>
           
          <data:post.commentRangeText/>
           
          <a expr:class='data:post.newLinkClass' expr:href='data:post.newerLinkUrl'><data:post.newerLinkText/></a>
           
          <a expr:class='data:post.newLinkClass' expr:href='data:post.newestLinkUrl'><data:post.newestLinkText/></a>
        </span>
      </b:if>

      <dl id='comments-block'>
        <b:loop values='data:post.comments' var='comment'>
          <dt expr:class='"comment-author " + data:comment.authorClass' expr:id='data:comment.anchorName'>
            <a expr:name='data:comment.anchorName'/>
            <b:if cond='data:comment.authorUrl'>
              <a expr:href='data:comment.authorUrl' rel='nofollow'><data:comment.author/></a>
            <b:else/>
              <data:comment.author/>
            </b:if>
            <data:commentPostedByMsg/>
          </dt>
          <dd class='comment-body'>
            <b:if cond='data:comment.isDeleted'>
              <span class='deleted-comment'><data:comment.body/></span>
            <b:else/>
              <p><data:comment.body/></p>
            </b:if>
          </dd>
          <dd class='comment-footer'>
            <span class='comment-timestamp'>
              <a expr:href='data:comment.url' title='comment permalink'>
                <data:comment.timestamp/>
              </a>
              <b:include data='comment' name='commentDeleteIcon'/>
            </span>
          </dd>
        </b:loop>
      </dl>

      <b:if cond='data:post.commentPagingRequired'>
        <span class='paging-control-container'>
          <a expr:class='data:post.oldLinkClass' expr:href='data:post.oldestLinkUrl'>
            <data:post.oldestLinkText/>
          </a>
          <a expr:class='data:post.oldLinkClass' expr:href='data:post.olderLinkUrl'>
            <data:post.olderLinkText/>
          </a>
           
          <data:post.commentRangeText/>
           
          <a expr:class='data:post.newLinkClass' expr:href='data:post.newerLinkUrl'>
            <data:post.newerLinkText/>
          </a>
          <a expr:class='data:post.newLinkClass' expr:href='data:post.newestLinkUrl'>
            <data:post.newestLinkText/>
          </a>
        </span>
      </b:if>

      <p class='comment-footer'>

        <b:if cond='data:post.embedCommentForm'>
          <b:include data='post' name='comment-form'/>
        <b:else/>
          <b:if cond='data:post.allowComments'>
            <a expr:href='data:post.addCommentUrl' expr:onclick='data:post.addCommentOnclick'><data:postCommentMsg/></a>
          </b:if>
        </b:if>

      </p>
END comment out for haloscan (part 2 - post) -->
<!-- start haloscan (part 2 - post) -->
      <script src='http://www.haloscan.com/load/tatata7' type='text/javascript'> </script>
<span class='post-comment-link'>
<p><a class='comment-link' expr:href='"http://www.haloscan.com/comments/tatata7/" + data:post.id + "/"' expr:onclick='"HaloScan(" + "\""+ data:post.id + "\"" + ");return false;"'>
<script type='text/javascript'>postCount('<data:post.id/>');</script>
</a> | 
<a class='comment-link' expr:href='"http://www.haloscan.com/tb/tatata7/" + data:post.id + "/"' expr:onclick='"HaloScanTB(" + "\""+ data:post.id + "\"" + ");return false;"'>
<script type='text/javascript'>postCountTB('<data:post.id/>');</script>
</a></p>
<script expr:src='"http://www.haloscan.com/comments/tatata7/" + data:post.id + "/?m=1"' type='text/javascript'/>
<noscript><a expr:href='"http://www.haloscan.com/comments/tatata7/" + data:post.id + "/"'>Comments</a> | <a expr:href='"http://www.haloscan.com/tb/tatata7/" + data:post.id + "/"'>Trackback</a></noscript><br/>
</span>
<!-- end haloscan -->



失敗の原因がよく分からないんですけど、何となくHTMLのコメント(<!-- -->)が怪しい気がします。でも、それだとみんな失敗するはずですね。今までにやったテンプレートの編集が関係しているのかなぁ。

Blogger Syntax Highliter with Perl support

[ja] Blogger Syntax HighliterをPerlのコードに対応させました。Perlのコードの場合はpreタグに class="perl" を指定します。ウィジェットを追加するには下のボタンを押して下さい。

[en] I added Perl code support to Blogger Syntax Highliter. For Perl code, use class="perl" in pre tag. Click the button below to add this widget.

Widget 追加ボタンの作り方

クリボウの Blogger Tips「Blogger beta の Widget 追加ボタンの作り方」 を読んで、Perl対応したBlogger Syntax Highlighterウィジェットの追加ボタンを作ってみようかなと思い始めました。Perlのキーワードや関数の対応が十分にできているかどうか分かりませんけど...

2008/07/26

Perlのコードをハイライトしてみる

Blogger Syntax Highlighterウィジェットをちょっと弄ってみました。

まぁ、やったことはウィジェット (JavaScript) の最後の方にあるRubyを処理する部分をコピーして、次のページを参考に内容を書き換えてRubyを処理する部分の下に追加しただけなんですけど。




正規表現がよくわかんないので、たぶんPerlの変数を上手く引っ掛けられないと思いますが、今後直そうと思います。

テストで表示させるのに "Hello, world!" ではつまらないしPerlの変数も出てこないので、オープンストリートマップで国土数値情報インポート作業用の資料を作る際に、ファイルをソートするために使った短いスクリプトが残っていたので、それにしました。

preタグに class="perl" を指定して、果たして上手くいくのか...

#!/usr/bin/perl

#####
#
# データ調査用スクリプト UTF8ファイルのSORT
#
# KSJ2 Railway Data 2007 - EB02 (Railway Line)
# 国土数値情報(鉄道データ)平成19年 国土交通省 - EB02 (鉄道路線)
#
# Files
#   Input : N02-07_EB02-r1.osm
#   Output : N02-07_EB02-r1-sort.osm
#    
#####


use strict;
use warnings;
use encoding "utf8";
use Encode;
use open IO => "utf8";


sub main() {

 open(IN, "<N02-07_EB02-r1.osm");
 open(OUT, ">N02-07_EB02-r1-sort.osm");

 my $i = 0;
 my @file = <IN>;
 my @array = sort @file;

 foreach my $line(@array) {
   print OUT $line;
   $i++;
 }

 close IN;
 close OUT;

 printf "Output %d records\n", $i;   

}




# run this script.

main();





うーん、やっと出た。

予想通り最初は正規表現の所がおかしくて、JavaScriptの実行自体がエラーになり、全くのプレーンテキストしか表示されませんでした。その後、キーワードや関数の名前を登録している部分、それに対応するCSSなども修正。これからも少しづつ直す所が出てきそうな気がします。

でも、とりあえず今の時点で動いているものを貼っておきます。

dp.sh.Brushes.Perl=function()
{var keywords='break continue do elsif else for foreach goto if last next return sub undef unless '+'until while';var builtins='abs accept alarm atan2 bind binmode bless caller chdir chmod chomp chop chown '+'chr chroot close closedir connect continue cos crypt dbmclose dbmopen defined '+'delete die do dump each eof eval exec exists exit exp fcntl fileno flock fork '+'format formline getc getlogin getpeername getpgrp getppid getpriority getpwnam '+'getgrnam gethostbyname getnetbyname getprotobyname getpwuid getgrgid '+'getservbyname gethostbyaddr getnetbyaddr getprotobynumber getservbyport '+'getpwent getgrent gethostent getnetent getprotoent getservent setpwent '+'setgrent sethostent setnetent setprotoent setservent endpwent endgrent '+'endhostent endnetent endprotoent endservent getsockname getsockopt glob gmtime '+'goto grep hex import index int ioctl join keys kill last lc lcfirst length '+'link listen local localtime log lstat m map mkdir msgctl msgget msgsnd msgrcv '+'my next no oct open opendir ord our pack package pipe pop pos print printf '+'prototype push q qq qr qx qw quotemeta rand read readdir readline readlink '+'readpipe recv redo ref rename require reset return reverse rewinddir rindex '+'rmdir s scalar seek seekdir select semctl semget semop send setpgrp '+'setpriority setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep '+'socket socketpair sort splice split sprintf sqrt srand stat study substr '+'symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied '+'time times tr truncate uc ucfirst umask undef unlink unpack untie unshift use '+'utime values vec wait waitpid wantarray warn write y'
this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:'comment'},{regex:dp.sh.RegexLib.DoubleQuotedString,css:'string'},{regex:dp.sh.RegexLib.SingleQuotedString,css:'string'},{regex:new RegExp(':[a-z][A-Za-z0-9_]*','g'),css:'symbol'},{regex:new RegExp('(\\$|@|%|\\*)\\w+','g'),css:'variable'},{regex:new RegExp(this.GetKeywords(keywords),'gm'),css:'keyword'},{regex:new RegExp(this.GetKeywords(builtins),'gm'),css:'builtin'}];this.CssClass='dp-pl';this.Style='.dp-pl .symbol { color: #a70; }'+'.dp-pl .variable { color: #a70; font-weight: bold; }'+'.dp-pl .builtin { color: #069; font-weight: bold; }';}
dp.sh.Brushes.Perl.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Perl.Aliases=['perl'];


桁番号表示のオプションは TeraPad みたいなものを勝手に想像していたので、ちょっとガッカリ。コードを見るにはメニューにある + expand source のリンクをクリックして下さい。

私はこれをウィジェット (JavaScript) の最後の方にある ['ruby','rails','ror']; で終わっている行の次に追加しています。

元のsyntaxhighlighterのページには"Code License: GNU Lesser General Public License"と書いてあるので、この部分もGLGPLということかな?  よくわからんけど...

2008年7月28日 追記

Perl対応部分を組み込んだウィジェットの追加ボタンを作成してみました。

おかげで、[設定] → [フォーマット] → 改行の変換を「いいえ」にして、自分でbrタグを入力して改行させなければいけなくなりました。「はい」だとウィジェットの中に在る改行までbrタグに変換されてしまうので...

コードをハイライトするウィジェット

クリボウの Blogger Tipsにコードをハイライトするウィジェットが紹介されていました。Bloggerにこんな機能を追加できるんですね。自分もウィキトラベルではJavaScriptやBookmarklet、オープンストリートマップではPerlのスクリプトを作ったりしているので面白そう。クリボウさんの記事を全部読んだ訳ではないので他にも同種のウィジェットが紹介されているかも知れませんが、とりあえず次の2つを書いておこうと思います。


ひとつはCode Prettifyウィジェットgoogle-code-prettifyを使ったもので、表示はIDEやソースコードに対応したテキストエディタのソースコード部分だけという感じです。

もうひとつはBlogger Syntax Highlighterウィジェット。元はsyntaxhighlighterで、行番号やメニュー(コードだけをポップアップウィンドウで表示、印刷、IEの場合のみクリップボードへのコピー)が表示されるほか、折りたたみ機能や桁番号表示のオプションもあるようです。私にとって残念なことはPerlには対応していないんですよね。

それぞれの表示例、導入方法、使用方法については以下のリンク先を参照して下さい。実際の投稿に必要なタグ・オプションの追加や記号の変換をしてくれるツールもリンク先で提供されています。



どちらを利用するか少し迷いましたが、コードをコピーする時に行番号が選択されず、折りたたみ機能も付いていて便利そうなので、Blogger Syntax Highlighterウィジェットを追加してみました。ちょっと弄ってPerlにも対応させられるといいなぁ。

2008年7月28日 追記

Blogger Syntax Highliter with Perl support を作ってみました。

2008/07/24

GPSロガーの設定をいぢってみる - 3

前回の続きです。

Wintec社のGPSロガー「Easy Showily (WPL-1000)」にプリセットされたGPSの受信設定の2つ目を試してみました。今回は2番の「標準精度」で、設定値の内容は次の通りです。


2.Middle Accuracy / 標準精度
GPS Parameters / GPS設定項目Values / 設定値
Fix mode / 測位モード3. 3D only
2D Fix Altitude[m] / 2D Fix高度500.00
Initial Min. SVs[3~6] / 初回衛星数4
Initial Signal Min. Strength[dBHz] / 初回信号強度25
Navigation Signal Min. Strength[dBHz] / 測位後信号強度18
P Accuracy Masks[m] / 測位精度マスク75
T Accuracy Masks[m] / 時間精度マスク150
PDOP Mask / PDOPマスク15.0
TDOP Mask / TDOPマスク15.0
SBASON


今回もログモードは前回と同じプリセットの1.Walk(歩行)を使用しました。その内容は複合条件(10秒毎, 20m毎, 最高時速=2000km/h, 最低時速=1km/h)です。

結果は前回とあまり違いがありませんでした。
Atom