MusicRider.com

余談

2007/04/03

「Suicaから、利用駅をぶっこぬいて経度緯度も取得する!」の巻き

(支離滅裂なので以下の文章読まないこと推奨)
zero3navi見て思ったのは、これとSFCPeep組み合わせれば、 去年のメディア芸術祭にあった Suicaの履歴から、利用駅を地図上に顕在化 のシンプルなやつが割と簡単に作れそうだなあと思って、作ろうとしてて、簡易乗り換えが検索すら実装できなくて頓挫してますが、途中の奴までのを公開。 (公開して、あまりのお粗末さにリファクタする気になるだろうというソリューション。メソッド名とかspyc参考にすればいいのかな)
/workspaceとかのパスは適時変えてください。
(経度緯度のechoまではw-zero3はいりません。ていうか、area.txtから日本測地系の経度・緯度とってこなくても、鉄道路線+駅位置情報データベース から世界測地系のをあれこれして、Google Mapと組み合わせてた方がオモシロイかも知れない。
ということで、Diggin_Util_ZeroThreeNaviクラス要らないか?(鉄道の路線以外(要するに道路)でarea.txtを利用するてのもありますが))

下のsfcpeep2zero3.phpでforeachでechoしてる部分をちょっと変えて、area.txtに上書きすれば、 利用駅の直線つなぎでの図示化はできるはず。
あと、下の3/21んとこで書いてる、 $requestのパラメータにSFCPeepからの利用駅(下の「ロケーション名から1経路内のロケーション名取得」メソッド使えば都内だと遠くはない駅すべてってことになるかな)渡すようにすれば、 駅名書かずに、イベント情報取得できるでしょう(試してない。)
ということで、次回はクラブサイトからイベント情報をスクレイプしてical形式にしてインポートし、ケータイで確認しやすくするの巻きです。(嘘。それPlaggerで………yamlなコンフィグんとこ含めて誰かやってほしいよなあ。テレビはまだしも雑誌の発売日とか、あとで買えばいいじゃんとか思う俺はダメダメですか。)
SFCPeep.exe > sfcpeep.txt
php /workspace//tests/Diggin/sfcpeep2zero3.php
<?php
//sfcpeep2zero3.php
require_once '/workspace//library/Diggin/Util/SfcPeep.php';
require_once '/workspace//library/Diggin/Util/ZeroThreeNavi.php';

/*sfcpeepから得られたデータを元に、利用駅を取得*/
$sfcpeep = file_get_contents('//SFCPeep20/sfcpeep.txt');
//$sfcpeep = mb_convert_encoding($sfcpeep, 'UTF-8', 'SJIS');
$sfc = new Diggin_Util_Sfcpeep($sfcpeep);
$stations = $sfc->getDistinctName(16);
print_r($stations); /*sfcpeepから得られたデータを元に、利用駅を取得 END*/

/* Zero3naviのエリア情報を利用して、経度緯度取得↑の利用駅だけechoで */
$areatxt = file_get_contents('/workspace//tests/Diggin/file/area.txt');
//$areatxt = mb_convert_encoding($areatxt, 'UTF-8', 'SJIS');
$zeroThreeNavi = new Diggin_Util_ZeroThreeNavi($areatxt);
//print_r($zeroThreeNavi->getLineData());

//$stations = array("日本橋","新宿");
foreach ($stations as $station){
	$var = $zeroThreeNavi->getLocateFromLocationNm($station);
	echo $var[0].",".$var[1].",".$station."\n";
}
/* ↑のechoの結果サンプル
139,48,27,35,44,47,北千住
139,43,03,35,33,18,蒲田
139,37,42,35,28,15,横浜
,,桜木町
*/
<?php
/**
 * Diggin_Util_Sfcpeep
 * 
 * @category Diggin
 * @package	 Diggin_Util
 */

class Diggin_Util_Sfcpeep
{
     private $_sfcpeep;
     
     protected $_sfcpeepRawData = null;
     protected $_sfcpeepData = null;
     
     /**
      * Constructor 
      * file関数や、キャッシュなどから受け取ったタブ区切りのデータをセット 
      * 
      * @param string $_sfcpeep
      */
     public function __construct($_sfcpeep)
     {
        $this->_sfcpeepRawData = $_sfcpeep;
     }
     
     /**
      * sfcpeepのデータから、[行数][項目]の配列を返します。
      * 
      * @return array
      */
     protected function _parseSfcPeep()
     {
         $rawdata = $this->_sfcpeepRawData;

         foreach(explode("\n", $rawdata) as $lineNum => $line){
             if (!empty($line)){
                 $item = explode("\t", $line);
                 $this->_sfcpeepData[$lineNum]["terminalHt"] = substr($item[0], 0, 4); //端末種履歴連番
                 $this->_sfcpeepData[$lineNum]["terminalCd"] = substr($item[0], 5, 2); //端末コード
                 $this->_sfcpeepData[$lineNum]["process"] = $item[1]; //処理
                 $this->_sfcpeepData[$lineNum]["date"] = $item[2]; //日付時刻
                 $this->_sfcpeepData[$lineNum]["inRailCd"] = $item[3]; //入線区コード
                 $this->_sfcpeepData[$lineNum]["inStationCd"] = $item[4]; //入駅順コード
                 $this->_sfcpeepData[$lineNum]["inCorp"] = $item[5]; //入会社
                 $this->_sfcpeepData[$lineNum]["inStation"] = $item[6]; //入駅名
                 $this->_sfcpeepData[$lineNum]["outRailCd"] = $item[7]; //出線区コード
                 $this->_sfcpeepData[$lineNum]["outStationCd"] = $item[8]; //出駅順コード
                 $this->_sfcpeepData[$lineNum]["outCorp"] = $item[9]; //出会社
                 $this->_sfcpeepData[$lineNum]["outStation"] = $item[10]; //出駅名
                 $this->_sfcpeepData[$lineNum]["balance"] = $item[11]; //残高
                 $this->_sfcpeepData[$lineNum]["historyNum"] = $item[12]; //履歴連番
             }
         }
         
         return $this->_sfcpeepData;
     }
     
     /**
      * 
      *
      * @return array
      */
     public function getSfcPeep() 
     {
         return $this->_parseSfcPeep();
     }
     
     /**
      * 入駅名, 出駅名をdistinctで返す。引数がnullだと店名なども返すので注意
      *
      * @param string $terminalCd //端末種コードの下2桁(16=改札、8=券売機)
      * @return array
      */
     public function getDistinctName($terminalCd = null)
     {
         $sfcpeep = $this->_parseSfcPeep();

         $result = array();
         foreach($sfcpeep as $line){
             if($line["inStation"]){
                 if(!empty($terminalCd) AND ($terminalCd == $line["terminalCd"])){
                     array_push($result,$line["inStation"]);
                 } else if (empty($terminalCd)) {
                     array_push($result,$line["inStation"]);
                 }
             }
             if($line["outStation"]){
                 if(!empty($terminalCd) AND ($terminalCd == $line["terminalCd"])){
                     array_push($result,$line["outStation"]);
                 } else if (empty($terminalCd)) {
                     array_push($result,$line["outStation"]);
                 }
             }
         }
         
         return array_unique($result);
     }
     
}    
<?php
/**
 * Diggin_Util_ZeroThreeNavi
 * 
 * @category Diggin
 * @package  Diggin_Util
 */

class Diggin_Util_ZeroThreeNavi
{

    private $_areatxt;
    
    public function __construct($_areatxt)
    {
       $this->_areatxt = $_areatxt;
    }
    
    /**
     * area.txtからの経路情報を配列取得
     * 
     * @param string $_areatxt
     * @return array
     */
    public function getLineData()
    {
        $lines = explode("#", $this->_areatxt);
        foreach ($lines as $lineNo => $line ) {
            if(trim($line)){
                $track = explode("\n", $line);
                array_pop($track);
                $nameAndColor = array_shift($track);
                list($data[$lineNo]["Name"], $data[$lineNo]["Color"]) = explode(",",$nameAndColor);
                foreach($track as $no => $location) {
                    $data[$lineNo]["locations"][$no]["keido"] = substr($location, 0, 9);
                    $data[$lineNo]["locations"][$no]["ido"] = substr($location, 10, 8);
                    $data[$lineNo]["locations"][$no]["locationNm"] = trim(substr($location, 19));
                }
            } 
        }

        return $data;
    }
    
    /**
     * ロケーション名から、経度・緯度取得
     * 
     * @param String $queryLocation
     * @return Array $keidoIdo
     */
    public function getLocateFromLocationNm($queryLocation)
    {
        
        $lineDatas = self::getLineData();
        $keidoIdo = array();
        
        foreach ($lineDatas as $lineData){
            foreach($lineData["locations"] as $location) {
                if ($location["locationNm"] == $queryLocation){
                    $keidoIdo = array($location["keido"], $location["ido"]);
                }
            }
        }
                
        return $keidoIdo;
    }  
    
    /**
     * ロケーション名から経路取得
     * 
     * @param string $queryLocation
     * @return Array
     */
    public function getLinesFromLocation($queryLocation)
    {
        $lines = array();
        $lineDatas = self::getLineData();
        
        foreach ($lineDatas as $lineData){
            foreach($lineData["locations"] as $location) {
                if ($location["locationNm"] == $queryLocation){
                    $lines[] = $lineData["Name"];
                }
            }
        }
                
        return $lines;
    }
    
    /**
     * 経路名からその1経路上のロケーション名取得
     * 
     * @param string $lineNm
     * @return Array
     */
    public function getLocationFromLineNm($lineNm)
    {
        $linesLocationNm = array();
        $lineDatas = self::getLineData();
        
        foreach($lineDatas as $lineDataCount => $lineData){
            if ($lineData["Name"] == $lineNm){
                $linesLocation = array_values($lineData["locations"]);
                foreach($linesLocation as $location) {
                     $linesLocationNm[] = $location["locationNm"]; 
                }
            }
        }
        
        return $linesLocationNm;
    }
     
    /**
     * ロケーション名から1経路内のロケーション名取得
     * 
     * @param String $queryLocation
     * @return Array
     */
    public function getLocationsByOneLine($queryLocation, $returnMethod = null)
    {
        $locates = array();
        $lines = array();
        
        $lines = self::getLinesFromLocation($queryLocation);
        foreach($lines as $line){
            $locates[] = self::getLocationFromLineNm($line);
        }
                
        return $locates;
    }    
}

2007/03/21

03naviは、素敵ツールだと思います。ということで、とりあえずEventcastから、zero3naviのevent.txtのフォーマットへのテキストを用意するスクリプトを書いた。(ちょ→てきとー)
XPとかからだとw-zero3本体のMy Documentsとか直接cdしてファイルを上書きとか難ありげなので用意するだけ。PerlCEとかnScriptとかならzero3単体でバッチ処理できそうだな。

サンプル//コマンドラインでの利用しか想定してません。
<?php
//pear install File
require_once 'File.php';
require_once 'library/Diggin/EventCast.php';

//config
$request = array("keyword" => "横浜",
                "username" => "    ",
                "tag" => "",
                "startdate" => "",
                "enddate" => "2007/09/30",
                "sort" => "date",
                "order" => "asc",
                "start" => "1",
                "results" => "100",
                "trim" => "0");

$evettxt = "event.txt";                
                
$event = new Diggin_EventCast($request);
foreach ($event->getItems() as $item){
    $date = split('/',$item["StartDate"]);    
    File::writeLine($evettxt, $request["keyword"]." ".(int)$date[1]."/".(int)$date[2]." ".$item["Title"]);   
}

	
<?php
/**
 * Diggin_EventCast
 * 
 * Author: Mika Sasezaki
 * 
 * あとでじっくりなおす。
 */

class Diggin_EventCast
{
    const EVENTCAST_BASE_URL = 'http://clip.eventcast.jp/api/v1/Search?';
    
    //今日:0、昨日から:-1
    const EVENTCAST_START_DATE_LINE = 0;
    const EVENTCAST_END_DATE_LINE = 30;
    const EVENTCAST_SORT = date;
    const EVENTCAST_ORDER = asc;
    const EVENTCAST_START = 1;
    const EVENTCAST_RESULTS_LIMIT = 50;
    //0:開催中のイベントを含む
    const EVENTCAST_TRIM = 0;
    
    private $request;
    
    protected $_keyword = null;
    protected $_username = null;
    protected $_tag = null;
    protected $_startdate = null;
    protected $_enddate = null;
    protected $_sort = null;
    protected $_order = null;
    protected $_start = null;
    protected $_results = null;
    protected $_trim = null;
    
    /**
     * コンストラクタ
     * 
     * @param String Keyword
     * @param Username
     * @param Tag
     * @param StartDate
     * @param EndDate
     * @param Sort
     * @param Order
     * @param Start
     * @param Results
     * @param Trim  
     */
    public function __construct($request) {
        if(!is_array($request)){
            $request = array($request);
        }
        
        $this->_keyword = trim($request['keyword']);
        $this->_username = trim($request['username']);
        $this->_tag = trim($request['tag']);
        $this->_startdate = trim($request['startdate']);
        $this->_enddate = trim($request['enddate']);
        $this->_sort = trim($request['sort']);
        $this->_order = trim($request['order']);
        $this->_start = trim($request['start']);
        $this->_results = trim($request['results']);
        $this->_trim = trim($request['trim']);
    }
    
    /**
     * EventCastへのリクエスト用URL生成
     * 
     * @return String
     */
    public function getRequestUrl() {
        $query = null;
        
        if ($this->_keyword) {
            $query .= "&Keyword=".$this->_keyword;
        }
        
        if ($this->_username) {
            $query .= "&Username=".$this->_username;
        }
        
        if ($this->_tag) {
            $query .= "&tag=".$this->_tag;
        }
        
        if ($this->_startdate) {
            $query .= "&StartDate=".$this->_startdate;
        } else {
            $dateS = date('Y/m/d', time()+86400*self::EVENTCAST_START_DATE_LINE);
            $query .= "&StartDate=".$dateS;        
        }
        
        if ($this->_enddate) {
            $query .= "&EndDate=".$this->_enddate;
        } else {
            $dateE = date('Y/m/d', time()+86400*self::EVENTCAST_END_DATE_LINE);
            $query .= "&EndDate=".$dateE;        
        }
        
        if ($this->_sort) {
            $query .= "&Sort=".$this->_sort;
        } else {
            $query .= "&Sort=".self::EVENTCAST_SORT;        
        }
        
        if ($this->_order) {
            $query .= "&Order=".$this->_sort;
        } else {
            $query .= "&Order=".self::EVENTCAST_ORDER;        
        }        
        
        if ($this->_start) {
            $query .= "&Start=".$this->_start;
        } else {
            $query .= "&Start=".self::EVENTCAST_START;        
        } 
        
        if ($this->_results) {
            $query .= "&Results=".$this->_results;
        } else {
            $query .= "&Results=".self::EVENTCAST_RESULTS_LIMIT;        
        }
        
        if ($this->_trim) {
            $query .= "&Trim=".$this->_trim;
        } else {
            $query .= "&Trim=".self::EVENTCAST_TRIM;        
        }
        
        $query = substr_replace($query, '', 0, 1);
        
        return self::EVENTCAST_BASE_URL.$query;
    }
    
    /**
     * PHPオブジェクト取得
     * 
     * @pararm String URL
     * @return Array
     */
    public function getEventCastPhpArray () {
        $url = $this->getRequestUrl()."&Format=php";
        return unserialize(file_get_contents($url));
    }
    
    /**
     * キーワード、タグにセットした地名とlocation.addressが
     * 一致しているものを配列として返す
     * …にしたい
     * 
     * @return Array
     */
    public function getItems() {
        $ecArray = $this->getEventCastPhpArray(); 
        return $ecArray["Items"];
    }
    
}

連絡先について

sasezaki @ gmail 。com ←のとこに送って下さい。
Hosting by XREA