2011年11月4日金曜日

JSON を使って配列の初期化

JSON の使い方のページを見るとオブジェクトの初期化方法を書かれているものが多く、単なるの配列の初期化方法はあまり書かれていません。 備忘録として記しておきます。

 1. 単純な配列を初期化
var a = ["abc", "def"];

2. 連想配列(オブジェクト)を初期化
var a = {"a":"abc", "b":"def"};

2011年10月6日木曜日

PHP HTMLタグの属性をパースする

HTMLタグの属性をパースする関数を作って見ました。
//====================================================================
//! タグの属性をパースする
//! 属性名はアルファベット, 記号(-_), 数字を認めます。
//! 値は "' での括りを認めます。
//! @param string $str タグの属性文字列
//! 例 type=submit type="submit" type='submit' checked
//! @return array キーが属性名の配列
//====================================================================
function aryParseTagAttribute( $str )
{
 //=== 正規表現 ===================================================
// $ma の要素番号
//  1                2 34                  5 67                    8 9
 $re = <<<_EOL_
/\s*([A-Za-z0-9_\-]+)(=(([^"'][^\s]*[^"'])|('(([^'\\\\]|\\\\.)*)')|("(([^"\\\\]|\\\\.)*)")))?/
_EOL_;
 $iMatches = preg_match_all( $re, $str, $ma );

 $aryAttr = array( );
 for ( $i = 0; $i < $iMatches; ++ $i )
 {
  //=== 属性名 =================================================
  $strName = $ma[1][$i];

  //=== 値を取得 ===========================================
  // type="submit"
  // $ma[] は (かっこの順にサブ文字列を格納している
  if ( !empty( $ma[4][$i] ) )
   $strValue = $ma[4][$i]; // 括り無し
  else if ( !empty( $ma[6][$i] ) )
   $strValue = $ma[6][$i]; // '' 括り
  elseif ( !empty( $ma[9][$i] ) )
   $strValue = $ma[9][$i]; // "" 括り
  else
   $strValue = '';   // 値なし

  //============================================================
  $aryAttr[$strName] = $strValue;
 }

 //================================================================
 return $aryAttr;
}

◆テスト
$s = <<<_EOL_
type="text" name='DATE' onclick="func( '\"test\"' ); return" width=100
_EOL_;

$a = aryParseTagAttribute( $s );
print_r( $a );

◆実行結果
Array
(
    [type] => text
    [name] => DATE
    [onclick] => func( '\"test\"' ); return
    [width] => 100
)

2011年7月14日木曜日

PHP 住所から緯度/経度を取得

Google Geocoding API を使って住所から緯度経度を求めます。(めちゃめちゃ簡単です)

Windows 環境ですので文字コードは SJIS です。API呼び出し時に UTF-8 に変換しています。

APIのレザルトは JSON で受け取って配列にデコードしています。

このレザルトには住所などの情報も含まれていますが JSON ですので Windows で使用する場合は SJIS への変換が必要となります。

<?php
//================================================
// 住所 → 緯度/経度変換
//================================================
function strAddrToLatLng( $strAddr )
{
    $strRes = file_get_contents(
         'http://maps.google.com/maps/api/geocode/json'
        . '?address=' . urlencode( mb_convert_encoding( $strAddr, 'UTF-8' ) )
        . '&sensor=false'
    );
    $aryGeo = json_decode( $strRes, TRUE );
    if ( !isset( $aryGeo['results'][0] ) )
        return '';


    $strLat = (string)$aryGeo['results'][0]['geometry']['location']['lat'];
    $strLng = (string)$aryGeo['results'][0]['geometry']['location']['lng'];
    return $strLat . ',' . $strLng;
}


//================================================
echo strAddrToLatLng( '東京都青梅市' );
?>

実行結果

35.7879958,139.2758298

詳しい情報は Google Geocoding API サービス をご覧ください。

Google Static Maps API

携帯などで使う Java Script を使わない地図表示 API です。通常の Google Maps API に比べるととても手軽に使えます。

例: <img src="http://maps.google.co.jp/maps/api/staticmap?center=東京都青梅市&zoom=18&size=640x400&maptype=roadmap&sensor=false&markers=color:red|label:A|東京都青梅市" />



簡単に説明します。

URL: http://maps.google.co.jp/maps/api/staticmap

パラメーター

center カンマ区切り緯度経度または住所を示す文字列(UTF-8 & URL-encode)
zoom ズームレベル(0 ~ 21)
size(必須) 画像のサイズです。書式は [x]x[y] (例: 640x480)最大 640x640
format 画像のフォーマット
png8 または png(デフォルト): 8 ビットの PNG 形式
png32: 32 ビットの PNG 形式
gif: GIF 形式
jpg: JPEG 圧縮形式
jpg-baseline: 非プログレッシブの JPEG 圧縮形式
maptype 作成する地図のタイプ
roadmap:(デフォルト)Google マップ ウェブサイトで通常表示される標準の道路地図画像
satellite: 航空写真です。
terrain: 物理的な地形図画像
hybrid: 航空写真と道路地図を組み合わせたもの
mobile 地図を携帯端末で表示するかどうかを指定 (true or false)
language マップ タイルのラベルを表示する言語
markers マーカー
sensor(必須)アプリケーションがユーザーの位置情報を取得するのにセンサーを用いているか (true or false)

マーカー

マーカーはパラメーターを|で区切って記述
markers=markerStyles|markerLocation1|markerLocation2|...

マーカースタイル

size: マーカーのサイズを {tiny, mid, small} の中から指定
color: 24 ビット カラー(color=0xFFFFCC など)、または {black, brown, green, purple, yellow, blue, gray, orange, red, white}
label: {A~Z、0~-9} のセットから大文字の英数字を 1 文字
icon: マーカーのカスタム アイコンとして使用するための URL を指定。使用できる画像形式は PNG、JPEG、GIF(PNG推奨)
shadow:(デフォルトは true)画像に影を付けるかどうかを指定

2011年6月24日金曜日

Google Maps API 住所から地図を表示する

Google Maps API を使って住所から緯度経度を求めその地点の地図を表示してみました。

先にmapオブジェクトを作ってから住所を元に緯度経度をセットすると灰色の地図が結構長い時間表示されてしまうので、緯度経度取得のコールバックの中でmapオブジェクトを作成しています。

この中ではまったのはマーカーの表示でした。最初、タイトルを設定せずにマーカーを構築していたのですが、それだとマーカーが表示されませんでした><;
function OnLoad( )
{
 var latlng;
 var strAddress = "東京都青梅市東青梅1-7-7";

 var geocoder = new google.maps.Geocoder();
 geocoder.geocode
 ( 
  {
   'address': strAddress
  }
  , function( results, status )
  {
   if ( status != google.maps.GeocoderStatus.OK )
   {
    Debug( "status=" + status );
    return;
   }

   latlng = results[0].geometry.location;

   // 地図を作成
   var map = new google.maps.Map
   (
    document.getElementById("map_canvas")
    , { 
     zoom: 15,
     center: latlng,
     mapTypeId: google.maps.MapTypeId.ROADMAP
    }
   );

   // マーカーを作成
   var marker = new google.maps.Marker( { positon: latlng, map: map } );
   var marker = new google.maps.Marker
   (
    {
       position: latlng
     , map: map
     , title: "(株)クレアンスメアード"
    }
   ); 

   // ポップアップ設定
   var infowindow = new google.maps.InfoWindow
   (
    {
       content: '(株)クレアンスメアード<br>0428-23-3120<br>'
     , size: new google.maps.Size( 450, 150 )
    }
   );
   google.maps.event.addListener
   (
      marker
    , 'click'
    , function( )
    {
     infowindow.open( map, marker );
    }
   );
  }
 );
}

2011年6月6日月曜日

PHP 参照の困った仕様(バグ?)

参照を使った場合のおかしな動作を見つけました。(5.1.6 & 5.3.5)
$a = array( 1, 2, 3 );
foreach ( $a as &$i ) echo $i;
echo ',';
foreach ( $a as $i ) echo $i;

上記を実行すると
123,122
となります。
う~ん、2番目の foreach の際に最初の foreach の &$i が効いていると $a[2] = $a[0] となり出力は 123,121 となる気がするのですが…

2011年5月2日月曜日

SWAT: IEで日本語表示

他のブラウザーだと日本語で表示されるのにIE8でSWATの画面をひらくと英語になってしまいます。
IE8の言語の設定の問題だろうなと思ったのですがインターネットオプションで確認すると「日本語(日本)[ja-JP]」となっている…
なんだろうなぁ~と思っていたのですが、追加ボタンを押して一覧を見ると「日本語[ja]」ってのがあるじゃないですか!?

で、これを追加してみたらちゃんと日本語で表示されるようになりました。


2011年1月17日月曜日

Service にて画面解像度を取得

とりあえず Activity を使った普通のアプリ(WzEditor 形式のメモ帳編集アプリ)はなんとか出来上がりました。

そこで、今度は簡単な Widget に挑戦してみることにしました。
通常アプリとはだいぶ作りが違い制約も多い><;

まぁ、なんとかカレンダーを表示するところまではできたのですが、当月以外の日付のフォントを小さくしたくなりました。
で、フォントサイズを変えようとしたのですが RemoteViews で引き数が2つあるメソッドの呼び出し方がわからない><;

↓これを呼びたい
textView.setTextSize( TypedValue.COMPLEX_UNIT_DIP, textSize ); 

んじゃ、dp値から ピクセル数を計算するかと思ったのですが、サービスからでは context.getWindowManager()がエラーになる><;

ん~、しばらく悩んだのですが、 Android API 2.2 のドキュメントを見ていて見つけました。この方法だとどこからでも呼べそうです。

// Context の取得
Context context = this.getBaseContext( );
CamLog.Debug( "context = " + context.toString( ) );

// WindowManager の取得
WindowManager wm = (WindowManager)context.getSystemService( Context.WINDOW_SERVICE );
CamLog.Debug( "wm = " + wm.toString( ) );

// DisplayMetrics の取得
DisplayMetrics objMetrics = new DisplayMetrics( );
wm.getDefaultDisplay( ).getMetrics( objMetrics );
CamLog.Debug( "metrics = " + objMetrics.toString( ) );

CamLog.Debug( "scaledDensity = " + objMetrics.scaledDensity );

// 通常フォントサイズの取得
// fPixel * Metrics#scaledDensity = fDip
// fPixel = fDip / Metrics#scaledDensity
m_fFontSizeThis = FONT_SIZE_THIS / objMetrics.scaledDensity;
m_fFontSizeOther = FONT_SIZE_OTHER / objMetrics.scaledDensity;