2008/07/31

Blogger Slippy Map

[ja] Slippy Map MediaWiki Extensionからの出力を基にBlogger用のSlippy Mapウィジェットを作成しました。
divタグに幾つかの属性値を設定して使用します(使用例をご覧下さい)。
ウィジェットを追加するには下のボタンを押して下さい。
Firefox3とSafari3では動きますが、IE6では動きませんでした。
Firefox3、Safari3、IE6で動きました。

[en] I made a Slippy Map widget based on output from Slippy Map MediaWiki Extension.
Usage is just adding some attributes to div tag; see examples below.
To get this widget, click the button.
It works on Firefox3 and Safari3, doesn't work on IE6.
It works on Firefox3, Safari3 and IE6.






使用例 (Examples)




<div class="slippymap" lat="36" lon="139" z="3" style="width:250px;height:200px;"></div>






<div class="slippymap" lat="52.516" lon="13.378" z="9" style="width:300px;height:300px;"></div>






<div class="slippymap" lat="51.5012" lon="-0.123" z="14" style="width:500px;height:400px;"></div>





履歴 (History)

0.1
2008-07-31 新規作成。Firefox3とSafari3で動作。
0.1.1
2008-08-02 IE6で動作。

Slippy Mapのウィジェットを作ってみる

Blogger上でSlippy Mapを一応表示できるようになったので、ウィジェットとして作ってみることにしました。

前回は「地図作成時のオブジェクト名」と「地図描画スペースとなるdiv要素のid」が共に"map"だったので、1ページに複数のSlippy Mapを表示させるには、この組み合わせ毎にユニークにしてあげればいっかなーと考えていましたが、普段からJavaScriptなどをやり慣れていない私にはそれほど単純ではありませんでした。


とりあえずコードを書いて1ページに複数のSlippy Mapを表示させようとすると、前回のSlippy Mapを含めて、どれか1つしかタイルが読み込まれませんでした。コードと睨めっこしても他にユニークにするべきところも無さそうだしJavaScript自体は動いているので、もしかしたらOpenLayersの制約かななどと思いながらコードを眺めていると、window.onload=init; と書かれた行が目に留まりました。色々検索しているうちに次のページが見付かったので参考にさせてもらいました。



単純に window.onload を使わないようにコードを修正すると、1ページに複数のSlippy Mapを表示させることができるようになりましたが、よーっく地図を見ると全て同じ座標とズームレベルになっています。地図そのもののオブジェクトだけでなく、座標とズームレベルのオブジェクトも別の名前で作ってあげないと駄目みたいですね...

このウィジェットの追加ボタンのページを作成して、そちらに簡単な使用例を載せておきます。

現時点のコード(一応完成版)はこちら。( "+ expand source" のリンクをクリックして下さい。)
<style>
.slippymap img { padding: 0px !important; border: none !important;}
</style>
<!-- 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"><!--
// Blogger Slippy Map 0.1
var i = 0;
var lat = 54;
var lon = 0;
var z = 4;
var style = "width:300px; height:200px;";
var element1, element2, element3, text;
var tags = document.getElementsByTagName("div");

  for ( var j=0; j < tags.length; j++ ) {

    if ( tags[j].className == "slippymap" ) {

      i++;

      if ( tags[j].getAttribute("lat") ) {
         lat = tags[j].getAttribute("lat");}
      if ( tags[j].getAttribute("lon") ) {
         lon = tags[j].getAttribute("lon");}
      if ( tags[j].getAttribute("z") ) {
         z = tags[j].getAttribute("z");}
      if ( tags[j].getAttribute("style") ) {
         style = tags[j].getAttribute("style");}

      element1 = document.createElement("script");
      element1.setAttribute("type","text/javascript");
      text = document.createTextNode("var lat"+ i + "=" + lat + "; var lon"
        + i + "=" + lon + "; var zoom"+ i + "=" + z + "; var map" + i
        + "; 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); } ;"
        + "if (typeof window.addEventListener == 'function') { "
        + "window.addEventListener('load', init, false);} else if (typeof "
        + "window.attachEvent == 'object') { window.attachEvent('onload', "
        + "init);} else { var oldonload = window.onload ; if (typeof "
        + "window.onload != 'function') { window.onload = init;} else { "
        + "window.onload = function() { oldonload(); init(); } } };"
        + "function init() { map" + i + " = new OpenLayers.Map('map" + i 
        + "', { 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" + i + ".addLayer(mapnik);"
        + " var osmarender = new OpenLayers.Layer.OSM.Osmarender('Osmarender'); "
        + "map" + i + ".addLayer(osmarender); var cyclemap = new OpenLayers"
        + ".Layer.OSM.CycleMap('Cycle Map'); map" + i + ".addLayer(cyclemap); "
        + "var maplint = new OpenLayers.Layer.OSM.Maplint('Maplint'); map" + i 
        + ".addLayer(maplint); var lonLat" + i + " = lonLatToMercator(new "
        + "OpenLayers.LonLat(lon" + i + ", lat" + i + ")); map" + i 
        + ".setCenter (lonLat" + i + ", zoom" + i + "); } ");
      element1.appendChild(text);
      tags[j].appendChild(element1);
      element1 = document.createElement("div");
      element1.setAttribute("class","tempmap");
      element1.setAttribute("style","margin-bottom:-35px;");
      <!-- define a DIV into which the map will appear -->
      element2 = document.createElement("div");
      element2.setAttribute("id", "map" + i);
      element2.setAttribute("style", style 
        + " border-style:solid; border-width:1px; border-color:#000;");
      element1.appendChild(element2);
      element2 = document.createElement("br");
      element1.appendChild(element2);
      element2 = document.createElement("span");
      element2.setAttribute("class","tempmap")
      element2.setAttribute("style",
        "font-size:70%; background-color:white; position:relative;top:-65px;left:5px;z-index:1003;");
      text = document.createTextNode("Data by ");
      element2.appendChild(text);
      element3 = document.createElement("a");
      element3.setAttribute("href","http://www.openstreetmap.org/?lat=" + lat 
        + "&lon=" + lon + "&zoom=" + z );
      element3.setAttribute("title","See this map on OpenStreetMap.org");
      text = document.createTextNode("OpenStreetMap");
      element3.appendChild(text);
      element2.appendChild(element3);
      element3 = document.createElement("br");
      element2.appendChild(element3);
      element3 = document.createElement("a");
      element3.setAttribute("href","http://creativecommons.org/licenses/by-sa/2.0/");
      element3.setAttribute("title","Creative Commons Attribution-Share Alike 2.0");
      text = document.createTextNode("CC-BY-SA-2.0");
      element3.appendChild(text);
      element2.appendChild(element3);
      element1.appendChild(element2);
      tags[j].appendChild(element1);
    }
  }
--></script>

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)です。

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

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

以下は、OSM.orgのUser Diaryに投稿した「[ja] GPSロガーの設定をいぢってみる - 2」を移動し、表やリンクなど一部を手直ししたものです。



前回の続きです。

「いぢってみる」と言っても、GPSロガーに何種類かプリセットされている設定値を試してみるだけなのですが...

私が使用しているGPSロガーはWintec社Easy Showilyというモデルで、型式はWPL-1000、"Auto-show Track Logger"と紹介されています。

ログモードの設定に関しては、3種類のプリセットと1種類のユーザー定義を単体で切り替えることができますが、ユーザー定義の内容はPCに繋がないと変更できません。

今回試そうとしているのはログモードではなくGPSの受信設定なのですが、こちらの方は5種類のプリセットと1種類のユーザー定義の切り替えとユーザー定義の内容の変更の両方ともPCに繋がないと行えません。面倒くさい... なので、5種類のプリセットを一通り試すのにも、ちょっと時間が掛かりそうです。

プリセットの番号順に試していこうと思うので、とりあえず最初は1番の「高精度」。設定値の内容は次の通りです。

1.High 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] / 測位後信号強度20
P Accuracy Masks[m] / 測位精度マスク50
T Accuracy Masks[m] / 時間精度マスク50
PDOP Mask / PDOPマスク10.0
TDOP Mask / TDOPマスク10.0
SBASON


ログモードはプリセットの1.Walk(歩行)を毎回使用する予定で、その内容は複合条件(10秒毎, 20m毎, 最高時速=2000km/h, 最低時速=1km/h)になっています。

結果はこんな感じです。

「高精度?」という気がしないでもないですが、まぁまぁですかね。素人には良く分かりませんが...

そう言えば、OSM.jpでrssフィードを受けられるようになったかな? 忙しそうだし、たぶんまだだろうなぁ。

Posted by Tatata at Wed Jul 23 12:35:00 +0100 2008

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

以下は、OSM.orgのUser Diaryに投稿した「[ja] GPSロガーの設定をいぢってみる - 1」を移動したものです。



This is my first diary post. Since it's hard for me to write a diary post in English, I'll do it in Japanese; sorry. :-)

OSM.jpでのrssフィードによるブログエントリ作成機能を使ってみることも兼ねて、ちょっとこちらに書いてみます。

えーっと、先日、東京の呉服橋交差点付近から丸の内1丁目・大手町・和田倉噴水公園・皇居東御苑を通って竹橋までマッピングしてきました。家に帰ってGPSのログを見てみると、これがもうグッチャグチャで、せっかく4時間近く歩いたのに使い物にならず、かなりショックを受けました。

ヘコミつつ取説を読み返すと「大気が不安定な時、GPSロガーから出力されるGPSデータは実際の位置データと異なるデータを示すときがあります」みたいなことが書いてあり、確かにこの日の朝はどんよりとして雨が降りそうな感じで、マッピングを行った午後も陽が差して暑かったですけど雲は結構あったように思います。

1ヶ月程前に皇居外苑をマッピングした時は、快晴ではないけど雲は多くなく暑い日で、結果はマッピングを開始した国際フォーラム横辺りから国道1号まではぶれていましたけどway pointを記録したタイミングはメモと合っていて、国道1号から先はtrack pointも使えました。

でも、このGPSロガーを今まで使ってきて、今回だけが結果に影響が出る程の天候だったとも思えないし、「なんでかなー?なんでかなー?」と思っている時、ふと思い出しました。そう言えば皇居外苑のマッピングの後に GPS reception を読んで、よく分かっていないくせにGPSロガーの設定を弄って、テストもせずにそのままにしていました。

天候が原因なのか設定が原因なのか、たぶん私では正確に分からないと思いますが、プリセットの設定をいくつか試してみて、その結果を次回以降のdiaryに書いておこうと思います。

Coordinates: 35.6851115538029; 139.763114997619 (map / edit)
Posted by Tatata at Sat Jul 05 07:46:02 +0100 2008

OpenStreetMapのUser diary

OpenStreetMapの本家のサイト http://www.openstreetmap.org/ にあるUser diaryを使ってみたのですが、「Previewが無い」「SaveするとEditできない」「HTMLのTableタグが上手く使えない」など長めのものを書くには使い難いと感じたので、こちら (Blogger) に引っ越すことにしました。

2008-08-25 追記
「SaveするとEditできない」と思っていたのですが、各エントリの一番下の行の右端に "Edit this entry" というリンクがありました。

2008/07/23

トルコ / カッパドキアのバルーンツアー

ウィキトラベルトルコカッパドキアの記事に予約代行業者のURLをしつこく載せる人がいるので、バルーン会社の情報をいくつか集めて、それらと一緒にカッパドキアの記事に載せてみることにしました。

以下は、そのバルーン会社の一覧。


  • Anatolian Balloons (アナトリアン・バルーンズ) — バルーン会社としては大手と思われる。貸切の料金は応相談。 所在 Adnan Menderes Cad. No: 34, Goreme - Nevsehir - TÜRK0YE 電話 +90 384 271 23 00 FAX +90 384 271 25 88 料金 Standard Flight € 150/人、Long Flight € 225/人。12歳以下は半額、6歳未満は搭乗不可。 WEB www.anatolianballoons.com e-mail info@anatolianballoons.com
  • Cappadocia Ez Air Balloons — バルーン会社としてはちょっとマイナーと思われる。そのためか、料金も少し安め。 所在 Kavaklionu Mah. No:8/A Urgup, Nevsehir, Turkiye 電話 + 90 384 341 7096 FAX + 90 384 341 7096 料金 大人 € 160/人、6歳未満 € 80/人。 WEB www.ezairballoons.com e-mail info@ezairballoons.com
  • Goreme Balloons (ギョレメバルーン) — 事情により日本人には避けられているが、なぜか欧米人には一番人気と言われているバルーン会社。 所在 Kayseri Cad. Altikapili Mah. No:13 Urgup, Nevsehir, Turkey 電話 +90 (384) 341 56 62, +90 (532) 416 64 61 FAX +90 (384) 341 72 45 料金 Standard Balloon Tour € 160/人、Deluxe Balloon Tour € 230/人。12歳以下は半額、6歳未満は無料。 WEB www.goremeballoons.com e-mail info@goremeballoons.com
  • Kapadokya Balloons (カッパドキア・バルーンズ) — バルーン会社としては大手と思われる。メールアドレスはwebのcontactページを参照。 所在 Nevsehir, Turkey 電話 +90 (0) 384 271 2442 FAX +90 (0) 384 271 2586 料金 € 250/人。 WEB www.kapadokyaballoons.com


ちょっと理由があって、予約代行業者はここに載せていません。

2008/07/20

eneloop

大きなパッケージでまとめ買いしていたアルカリ電池を使い果たし、暫くの間はマッピングに行って電池が無くなる度にコンビニやキオスクで買っていましたが、次第に馬鹿らしくなって来たので三洋電機のeneloop(エネループ)を買ってみました。



実際にGPSロガーでエネループを使ったみたところ、計った訳ではありませんが、今までの電池よりも長持ちするような気がします。そう思いながら暫く使っていると、先日、徒歩で20分の道程のちょうど真ん中あたりで電池切れになってしまいました。もちろんスタート時に電池残量の警告は表示されておらず、いつもは(アルカリ電池を使っていた時は)警告が表示されてからも30分程度は使用できていたので、ちょっとビックリです。どうやらこれはエネループの放電カーブの特性によるもののようで、リンク先のKansai-Event.comのページには「残量メーターが付いている機器で使用される方は注意が必要かもしれません。」と書かれていました。

今までのマッピングではほとんどの場合に区切りの良い場所で電池交換ができていたけど、これからは電池残量の警告が表示されたら出来るだけ早く電池交換をしないといけないなぁ。でも、エネループは「つぎ足し充電OK」なんだから、マッピングに出掛ける前に毎回交換して、帰って来たら即充電という習慣を付ければいいのか...

2008/07/15

GPSのログモード

先日、OpenStreetMapの日本語メーリングリスト (Talk-ja) でログモードについて話題になっていたので、メモを書いておこうと思います。


自転車や徒歩でマッピングする時にGPSのトラックログの頻度をどうしているかという話でしたが、これについてはOSMのwikiにあるFAQのページに "Why are the points on my tracks spaced out?" という節があり、この中で「自動車や自転車の場合は1秒間隔、徒歩の場合は2~3秒間隔にすると良い」と書かれています。この解説はガーミン社ハンディGPS(トラックログの容量が10,000ポイント)を前提に書かれているようですが、その他のGPSロガーでも参考にできそうです。

MLではマップコンシェルジュ古橋さんから、普段の設定やOSM用GPSロガー購入時のチェックポイントについてアドバイスがありました。その中に「最大速度の上限も有効になれば、ノイズもかなりとれる」と書かれており、その点が気になっています。自分のGPSロガーが対応しているか、なるべく早い内に試したいと思います。上手く行けば、街中のログがあまりグチュグチュにならずにすみそうなので...

2008/07/14

Test1

<div class="slippymap" lat="36" lon="139" z="3" style="width:200px;height:150px;"></div>






<div class="slippymap" lat="35.6775" lon="139.7625" z="13" style="width:300px;height:300px;"></div>






<div class="slippymap" lat="35.577" lon="140.256" z="10" style="width:500px;height:400px;"></div>

Test

<div class="slippymap" lat="36" lon="139" z="4" style="width:250px;height:200px;"></div>
<div class="slippymap" lat="35.6775" lon="139.7625" z="14" style="width:300px;height:300px;"></div>





Atom