2009-09-30

Google Static Maps APIのいい感じのズームサイズを決定する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Google Static Maps APIを使っているとある2点が一画面に収まるような感じのズームサイズを決定したくなることがあります。

pythonで以下のような感じで求められそうです。

#2つの指定座標が収まるズームサイズを求める
#sizeは画像サイズ(正方形地図を利用としています)
# 長方形の場合は、二つの値を受け取ってそれぞれに対して
# zoomを計算して小さい方を選べばよいと思います。
#x1,y1はポイント1の緯度経度
#x2,y2はポイント2の緯度経度
def get_zoom_size(size,x1,y1,x2,y2):
dx = float(x1)-float(x2)
dy = float(y1)-float(y2)
d=math.sqrt(dx*dx+dy*dy)
if d==0:
return 14
zoom = math.log(float(size)/d)/math.log(2)
return int(math.floor(zoom))

floatやらintやらがこなれていない感じがビンビンしてますが、なんとなく出ている感じがするので、まぁよしとしましょう。
これは、
Google Static Maps API で表示した画像の端っこの緯度経度を調べる
で紹介した以下の式を変形させて出してみました。
lx=float(xsize)/pow(2,float(zoom))

2009-09-29

pythonでモバイルAdSenseを使ってみる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
※この方法では、広告は表示されますがカウントがされていないことがわかりました。
※カウントされる方法はまだわかりません。
※※ カウントされないのはGoogle App Engineに配置したときのケースのようです。(追記 2010/5/20)

携帯用のAdSenseを利用する場合は、PHP,perlなどのコードを貼り付けなさいと最終的になります。
GoogleAppEngineを使っているならば、pythonで使ってみたくなるのです。
なのでPythonで使ってみました。
GoogleAppEngineでないならばurlfetchの部分は置き換えが必要です。
後は、自分用の設定にするにはモバイルAdSenseで生成されたPHPなどのコードを見ながら適切に自分用の値を設定する必要があります。

# -*- coding: utf-8; -*-
from time import time
from math import floor
from urllib import urlencode
from google.appengine.api import urlfetch

def google_append_color(color,dt):
color_array = color.split(',')
return color_array[int(dt % len(color_array))]

def google_ad(request):
scheme = 'https://' if request.is_secure() else 'http://'
dt = time()
params = {
'ad_type':'text_image',
'channel':'設定したいchannelのコードを設定',
'client':'ca-mb-' + '自分のAdSenseの値を設定',
'dt':repr(floor(dt*time())),
'format':'mobile_single',
'https':request.META.get('HTTPS', ''),
'ip':request.META.get('REMOTE_ADDR', ''),
'markup':'xhtml',
'oe':'utf8',
'output':'xhtml',
'ref':request.META.get('HTTP_REFERER', ''),
'url':scheme + request.META.get('HTTP_HOST', '') + request.META.get('REQUEST_URI', ''),
'useragent':request.META.get('HTTP_USER_AGENT', ''),
'color_border':google_append_color('ここは色をカスタマイズするならば利用',dt),
'color_bg':google_append_color('ここは色をカスタマイズするならば利用',dt),
'color_link':google_append_color('ここは色をカスタマイズするならば利用',dt),
'color_text':google_append_color('ここは色をカスタマイズするならば利用',dt),
'color_url':google_append_color('ここは色をカスタマイズするならば利用',dt),
}
screen_res = request.META.get('HTTP_UA_PIXELS', '')
delimiter = 'x'
if screen_res == '':
screen_res = request.META.get('HTTP_X_UP_DEVCAP_SCREENPIXELS', '')
delimiter = ','
if screen_res == '':
screen_res = request.META.get('HTTP_X_JPHONE_DISPLAY', '')
delimiter = '*'
res_array = screen_res.split(delimiter)

if len(res_array) == 2:
params['u_w'] = res_array[0]
params['u_h'] = res_array[1]

muid = request.META.get('HTTP_X_DCMGUID', '')
if muid != '':
params['muid'] = muid
muid = request.META.get('HTTP_X_UP_SUBNO', '')
if muid != '':
params['muid'] = muid
muid = request.META.get('HTTP_X_JPHONE_UID', '')
if muid != '':
params['muid'] = muid
muid = request.META.get('HTTP_X_EM_UID', '')
if muid != '':
params['muid'] = muid

url = 'http://pagead2.googlesyndication.com/pagead/ads?' + urlencode(params)
result = urlfetch.fetch(url)
if result.status_code != 200:
return None
return result.content

このgoogle_adで返された値を広告を貼り付けたい位置に出力するようにすればよいです。
一応、試したら見ることはできたので動いているようです。

2009-09-24

携帯で位置情報を取るには、Cirius LabさんのGeoFormAPIがステキ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
携帯サイトの醍醐味の一つは位置情報を取れることだと思うのですが、各会社毎に取得する手段が違うし、同じ会社でもGPSを使うものと基地情報(?)を使うものといろいろなわけです。
そんな違いを吸収してくれるのがCirius LabさんのGeoFormAPIなのです。
詳細は、以下をみてください。
http://lab.cirius.co.jp/index.php?GeoPlatformAPI%2FGeoFormAPI
これを利用すると、位置情報を取得するためのリンクを生成してくれます。
生成した情報をクリックすると位置情報を取得して、指定したurlに位置情報をつけてもどしてくれます。

pythonさんで利用するには、以下のような感じです。
利用前提はgoogle app engineなのでurlfetchを使っていますが、使わないときは適当に置き換えてください。
またdjangoを利用するのでrequestオブジェクトを受け渡しています。環境変数を取るときは違う手段を使っても良いと思います。

# -*- coding: utf-8; -*-
from urllib import urlencode
from google.appengine.api import urlfetch

def get_geo_form(request,return_uri,w='現在位置で探す'):
params = {
'ua':request.META.get('HTTP_USER_AGENT', ''),
'return_uri':return_uri,
'api_key':'APIを利用するためのAPIキーを指定します。',
'display':w,
}
url = 'http://api.cirius.co.jp/v1/geoform/xhtml?' + urlencode(params)
result = urlfetch.fetch(url)
if result.status_code != 200:
return None
return result.content


get_geo_formによって、リンクのhtmlを返すのでこれをそのまま使いたい場所に埋め込むことになります。

docomoでinputタグはformできちんと囲わないと出力されない

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
docomo用のサイトをちょっといじっていて
<input type="text" value="test">
のようにテキストボックスを単独で表示しようとしたら表示されませんでした。

きちんと
<form action="/dummy">
<input type="text" value="test">
</form>
のようにformタグで囲わないと出力されないようです。
formタグで囲うときは、最低限actionは指定しないといけない感じです。

2009-09-23

pythonさんでジオコーディングと逆ジオコーディング

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
場所の名前から緯度経度取得するジオコーディングをpythonでやってみました。

google mapを利用します。
ジオコーディングに関しては、
http://code.google.com/intl/ja/apis/maps/documentation/services.html#Geocoding_Direct
に書いてあります。

コードは以下のような感じです。
google app engineで利用することを前提にしているので
urlfetchを使っていますが、そうでないならばそこを置き換える必要があります。

# -*- coding: utf-8; -*-
import xml.etree.ElementTree as etree
import urllib
from google.appengine.api import urlfetch

#場所名から緯度経度取得
def geocoding(addr):
url = 'http://maps.google.com/maps/geo?'
url = url + 'key=' + 'グーグルマップAPIのキー'
url = url + '&sensor=false'
url = url + '&output=xml'
url = url + '&q=' + urllib.quote(addr.encode('utf-8'))
result = urlfetch.fetch(url)
if result.status_code != 200:
return None
dom = etree.fromstring(result.content)
namespace ='http://earth.google.com/kml/2.0'
code = dom.findtext('.//{%s}code' % namespace)
if code != "200":
return None
point = dom.findtext('.//{%s}coordinates' % namespace)
if point == None :
return None
tmp = point.split(',')
ret = {}
ret['lon'] = tmp[0]
ret['lat'] = tmp[1]
return ret


緯度経度から場所の名称を取得する逆ジオコーディングもgoogle map apiでできることを
http://creco.net/2009/03/07/implement_google_reverse_geocoding_api/
で知りましたので、こちらも試してみました。

コードは以下のような感じです。
取得できる場所の名称が道路名だったり郵便番号だったりするケースを除外するためにAddressDetailsのAccuracyを確認する必要があるのですが、AddressDetailsのネームスペースが他と違っているので、そこが注意ポインツです。
しばらく気づかずにAddressDetailsの情報が取れなくて悩んでしまいました。

# -*- coding: utf-8; -*-
import xml.etree.ElementTree as etree
import urllib
from google.appengine.api import urlfetch

#緯度経度から場所名取得
def regeocoding(lat,lon):
url = 'http://maps.google.com/maps/geo?'
url = url + 'key=' + 'グーグルマップAPIのキー'
url = url + '&hl=ja'
url = url + '&oe=UTF8'
url = url + '&output=xml'
url = url + '&q=' + str(lat) + ',' + str(lon)
result = urlfetch.fetch(url)
if result.status_code != 200:
return None
logging.info(result.content)
dom = etree.fromstring(result.content)
namespace ='http://earth.google.com/kml/2.0'
code = dom.findtext('.//{%s}code' % namespace)
if code != "200":
return None
for placemark in dom.findall('.//{%s}Placemark' % namespace):
ad = placemark.find('.//{urn:oasis:names:tc:ciq:xsdschema:xAL:2.0}AddressDetails')
if ad.get("Accuracy") == "5" or ad.get("Accuracy") == "6":
continue
else :
addr = placemark.findtext('.//{%s}address' % namespace)
break
addr = addr.replace(u'日本', '', 1)
return addr

2009-09-20

Google Static Maps API で表示した画像の端っこの緯度経度を調べる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Google Static Maps APIで地図画像を作成できますが、作成した画像の一番上やら右端などがどんな緯度経度なのかを知りたいときがあります。

方法としては、
http://da-studio.blogspot.com/2008/04/google-static-maps-api.html
を見ればわかります。

理論に関しては、まったくわからないですが
ズームサイズと画像サイズから、地図に表示されている
(地図の一番上の座標)-(地図の一番下の座標)
の値がわかるようです。

これがわかれば、中心座標に求めれた数値の半分を足したり引いたりすれば、端っこの座標を求めることができるのです。

リンク先にphpのサンプルコードがあるので、こちらではpythonのコードを書いてみます。

#画像縦サイズ:ysize
#画像縦サイズ:xsize
#画像中心緯度:clat
#画像中心軽度:clon
#縦横の表示域を算出
lx=float(xsize)/pow(2,float(zoom))
ly=float(ysize)/pow(2,float(zoom))

#小数点以下をいい感じに丸める処理
lattop = round((float(clat)+ly/2)*1000000)/1000000
latbtm = round((float(clat)-ly/2)*1000000)/1000000
lontop = round((float(clon)+ly/2)*1000000)/1000000
lonbtm = round((float(clon)-ly/2)*1000000)/1000000


表示域を算出するときに、念のため値をfloatで囲んでおくのが良さげです。
何も考えずに使っていたら、それぞれintとして取り扱うコードになっていて、
算出結果が0とかになったりしたもので。

2009-09-19

pythonで'cp932 codec can't decode bytes in position illegal multibyte sequence'ってエラー

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
windows環境でpythonさんをいじっているのですが、
日本語を扱うところで
cp932 codec can't decode bytes in position illegal multibyte sequence
みたいな感じのエラーがでました。

コード的には、

w = "日本語"
ww = "aaa" + w + "bbb"

みたいな感じの2行目の部分で出ました。

とりあえずコードの頭に
# -*- coding: utf-8; -*-
とかつけているからコード内の日本語はutf-8で扱われるのかと思っていたのですが
cp932とか言われてちょっとよくわからず。
でも、

w = u"日本語"
ww = "aaa" + w + "bbb"

とユニコードにしておいたら消えました。

pythonの日本語系の取り扱いは、まだしっくりせずです。

2009-09-18

Djangoのテンプレートのフィルタのescapejs

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Djangoさんのテンプレートには、フィルタというものがついていてテンプレートにセットされた値にテンプレート側で値に対して修正を書けることができます。

Djangoさんのテンプレートないでjavascriptを記述していて、そのスクリプト内にある文字列を変数に代入しようとして

var aaa = "{{ test }}";

なんてしておいた時に、testの値に改行などが入っていた際には、javascriptが動かなくなります。

そんな感じを防止するために

var aaa = "{{ test|escapejs }}";

のような感じでescapejsというフィルターを使うとエラーにならないようにしてくれます。

でも、html的に安全でないとかいう感じで書いてあったので、私はこんな感じにしてみました。

var aaa = "{{ test|striptags|escapejs }}";


便利なDjangoのテンプレートのフィルターは、
http://djangoproject.jp/doc/ja/1.0/ref/templates/builtins.html#ref-templates-builtins-filters
で確認できます。

フォームのテキストエリアなどにデフォルトを表示してフォーカスを当てると消えるやつ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
フォームにデフォルト値を入れておいて、実際にフォーカスをあてて入力を行う際には、そのデフォルトが消えるというやつです。
jQueryのプラグインであるjQuery Watermark Pluginを使うと実現できます。

利用方法は、
http://www.skuare.net/2009/04/javascriptjquery_watermark_plu.html
を見ればよいです。

ポイントは、デフォルト文字の表示のされ方を指定するためにupdnWatermarkというクラスのcssを準備しておく必要があります。

jQuery Watermark Pluginからダウンロードするとサンプルがあるので、それをそのまま利用するのが簡単だと思います。

ただこのサンプルでは、CSSフレームワークであるBlueprintを利用していると気持ちのよい位置に文字が表示されませんでした。
なので私は、以下のような感じのcssを用意して使ってみました。

.updnWatermark label
{
position: absolute;
padding: 1em;
padding-left: 0.5em;
white-space: nowrap;
color: #999;
}

2009-09-13

Blueprint CSS

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Google app engine patchには、Blueprint CSSなるものが入っています。

これは、CSSフレームワークなるものらしいです。
CSSフレームワークとは、なんじゃらほい?という感じだったのですが、
フレームワークで準備したcssのクラスとかをいい感じでつかうと
いい感じのサイトが簡単にできちゃいますというものようです。

Blueprintの場合ですが、グリッドレイアウトというものが簡単に出来るようになるようです。
グリッドレイアウトとは、画面上の各要素をグリッドにきちんとあわせることできれいなサイトができあがるというもののようです。
そして、そのグリッドにきちんとあわせるというのが、私のような素人には結構たいへんな気配がするのです。
Blueprintでは、グリッドレイアウト意外にもブラウザのデフォルトの見た目をリセットしてBlueprintのいい感じの見た目を設定してくれているようでもあります。
それをできるようになるということなので、私も使ってみることにします。

Blueprintに関しては、
http://www.ideaxidea.com/archives/2009/01/blueprint_css.html
で情報がまとまっていて参考になります。

Blueprintは、グリッドが24個(デフォルトで変えられるようです)に分かれており、それぞれの要素で何個のグリッドを使うかを指定していく感じです。

具体的な利用法は、以下のような感じです。

CSS指定方法

<link rel="stylesheet" href="/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="/blueprint/print.css" type="text/css" media="print">
<!--[if lt IE 8]><link rel="stylesheet" href="/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->


実際にBlueprintを適用する範囲は、classでcontainerで指定したdiv範囲となります。
一緒に指定してあるshowgridを指定すると背景にうっすらグリッドを表示してくれてテスト時のデザインの参考になります。

<div class="container showgrid">
</div>


24個のグリッドをいくつかにdiv要素で分割して指定するには、span-*というクラスを指定します。
そして、一行に配置するグリッドは、合計24になるようにします。
そして、一行の終わりとなる要素にはlastというクラスを指定します。

<div class="container showgrid">
<div class="span-24 last">
<p>一行目は、24個のグリッドを一つの要素で使い切ります。</p>
</div>
<div class="span-8">
<p>2行目は3つの要素を配置します。</p>
</div>
<div class="span-8">
<p>2つ目の要素です。</p>
</div>
<div class="span-8 last">
<p>3つ目の要素です。行の最後なのでlastクラスを指定しています。</p>
</div>
</div>


div要素は、入れ子にできます。入れ子で指定するときは、利用グリッドの合計を親要素で利用しているグリッドの合計にする必要があります。

<div class="container showgrid">
<div class="span-12">
<p>この中を入れ子で指定します。</p>
<div class="span-5 colborder">
<p>ここで親グリッド12のうち5個利用します。colborderを指定したことで、5個のグリッドの後にグリッド一つ分の空白をあけることになります。なので合計6個分のグリッドをココで指定しています。</p>
</div>
<div class="span-6 last">
<p>入れ子でも、入れ子内で行の最後になった場合はlastクラスを指定します。</p>
</div>
</div>
<div class="span-12 last">
<p>行の最後なのでlastを指定しています。</p>
</div>
</div>


グリッド配置するときには、必ずしも1個目のグリッドから利用するわけでなく、途中のグリッドから利用したいこともあります。
そのときは、prepend-*とappend-*を利用します。prependを指定すると指定グリッド前に指定した数だけグリッドをあけてから要素を配置することになります。appendは要素の後に指定グリッド分あけることになります。

<div class="container showgrid">
<div class="span-8 prepend-4 append-5">
<p>グリッド4つ分あけてからグリッド8個分確保します。そしてその後に5個分のグリッドをあけます。つまり17個分ここで指定したことになります。</p>
</div>
<div class="span-7 last">
<p>隣の要素との間に5グリッド分の間が開いています。</p>
</div>
</div>


ここまで書いた要素をすべて一つのcontainerの中に入れたとしたら、以下のようなイメージになります。
あくまでもこんな感じになるというだけで、実際に以下はBlueprintを利用したものではないです。





一行目は、24個のグリッドを一つの要素で使い切ります。
2行目は3つの要素を配置します。2つ目の要素です。3つ目の要素です。行の最後なのでlastクラスを指定しています。
この中を入れ子で指定します。
ここで親グリッド12のうち5個利用します。colborderを指定したことで、5個のグリッドの後にグリッド一つ分の空白をあけることになります。なので合計6個分のグリッドをココで指定しています。 入れ子でも、入れ子内で行の最後になった場合はlastクラスを指定します。
行の最後なのでlastを指定しています。
 グリッド4つ分あけてからグリッド8個分確保します。そしてその後に5個分のグリッドをあけます。つまり17個分ここで指定したことになります。 隣の要素との間に5グリッド分の間が開いています。


他にも、見た目系をいじるクラスとかもあるようなのですが、そこまではまだ理解ができていません。

藤城清治さん

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
日本人なら一度は見たことがあると思われる影絵の作家さんです。

http://www.seiji-fujishiro.com/nn4/index.html

今日、銀座でやっている展覧会があり、ちょっと見てきました。特になんとも思っていなかったのですが、予想以上にステキでした。
色使いがとてもきれいで影絵の概念がちょっと変わってしまいました。
影絵でグラデーションがあるなんて思っていなかったものです。
そして藤城清治さんは、今年で86歳のようですが、2009年の作品などもあり、それがまたステキだったりするのです。
そんなこんなでオススメなのです。


2009-09-02

Eater-sagari

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク


なんか謎の生物な感じがキニナルのです。
パクっといろいろ食べるのです。

これは、なんかシリーズみたいになっているようです。
seto(セト)
がブランド名のようです。他にいかのようなものがありました。