Ejemplo n.º 1
0
 /**
  * 検索文字列を正規化してメンバ変数に格納する
  * @param string $address
  * @return void
  */
 protected function parse($address)
 {
     //全角数字を半角に。全角スペースを半角に。
     $address = mb_convert_kana($address, 'ns');
     //半角スペースを削除
     $address = str_replace(' ', '', $address);
     //県を特定し、検索文字列から県を除外
     foreach (Dm_Geocoder_Prefecture::get() as $code => $name) {
         $splited = preg_split('/' . $name . '/', $address);
         if (count($splited) <= 1) {
             continue;
         }
         $this->prefectureCode = $code;
         $this->prefectureName = $name;
         $address = $name . $splited[1];
         break;
     }
     //住所中の数値を漢数字に変換する
     $address = preg_replace_callback('/[0-9]+/msu', create_function('$mt', 'return Dm_Geocoder_Query::num2kan_decimal($mt[0]);'), $address);
     //都道府県名以降の住所
     $this->address = $address;
 }
Ejemplo n.º 2
0
 /**
  * csvを検索文字列で検索し、検索結果としてマッチする候補を複数返す
  * 
  * 検索速度を速くするため、少し処理が複雑になっています
  * 都道府県、市区町村、大字町丁目名と、段階的に検索をかけていきます。
  * 
  * @param Dm_Geocoder_Query
  * @return Dm_Geocoder_Address[]
  */
 public static function find(Dm_Geocoder_Query $query)
 {
     // 都道府県を特定できていれば絞り込む
     if ($query->prefectureCode) {
         //入力された権のみを検索対象とする
         $prefectureCodes = array($query->prefectureCode);
         //検索文字列の頭に県名がついていれば削除する
         $needle = mb_substr($query->address, mb_strlen($query->prefectureName));
         //県名のみの検索の場合は該当県のAddressを全件返して終了
         if (strlen($needle) === 0) {
             return Dm_Geocoder_GISCSV_Reader::readAll($query->prefectureCode);
         }
     } else {
         //全件を検索対象とする
         $prefectureCodes = array_keys(Dm_Geocoder_Prefecture::get());
         //検索対象文字列
         $needle = $query->address;
     }
     $finded = array();
     foreach ($prefectureCodes as $prefectureCode) {
         //CSVを読み込む
         $giscsv = new Dm_Geocoder_GISCSV($prefectureCode);
         $buf = $giscsv->read();
         //都道府県名以降の文字列を市区町村名とマッチングして
         //1文字ずつCSVから正規表現で検索する
         $findedInPref = array();
         $code = '\\"\\d+\\"';
         $l = mb_strlen($needle);
         for ($i = 1; $i <= $l; $i++) {
             $mun = mb_substr($needle, 0, $i);
             $mun = preg_quote($mun);
             $mun = '\\"' . $mun;
             $pattern = '/^' . $code . ',\\"[^\\"]+\\",' . $code . ',' . $mun . '.+$/m';
             preg_match_all($pattern, $buf, $match);
             //1件も一致しなければ終了
             if (count($match[0]) === 0) {
                 break;
             }
             //1件でも一致していれば保持する。これまでのものは破棄する。
             $findedInPref = array();
             foreach ($match[0] as $key => $row) {
                 $address = new Dm_Geocoder_Address();
                 $findedInPref[] = $address->importCsv($row);
             }
         }
         $finded = array_merge($finded, $findedInPref);
     }
     //これまでに検索した行は市区町村レベルのマッチングだったので
     //今度は大字町丁目名までを使って1行1行マッチングする
     $addressMatchedMost = array();
     $addressMatchedMostLength = 0;
     foreach ($finded as $key => $row) {
         //市区町村と大字町丁目名で検索する
         $matchesLength = self::forwardMatchesLength($row->municipalityName . $row->localName, $needle);
         if ($matchesLength === 0) {
             continue;
         }
         if ($matchesLength > $addressMatchedMostLength) {
             $addressMatchedMostLength = $matchesLength;
             $addressMatchedMost = array($row);
         } else {
             if ($matchesLength === $addressMatchedMostLength) {
                 $addressMatchedMost[] = $row;
             }
         }
     }
     return $addressMatchedMost;
 }
Ejemplo n.º 3
0
 /**
  * _debugPrefLocation
  * 
  * 県に所属する大字町丁目の緯度経度の最小と最大をechoします。
  * デバッグ用メソッドです。
  * 
  * @return void
  */
 public static function _debugPrefLocation()
 {
     $prefectures = array_keys(Dm_Geocoder_Prefecture::get());
     $prefectureLocation = array();
     foreach ($prefectures as $prefecture) {
         $reader = new Dm_Geocoder_GISCSV_Reader($prefecture);
         foreach ($reader as $key => $row) {
             if (!isset($prefectureLocation[$prefecture])) {
                 $prefectureLocation[$prefecture] = array('minLat' => $row->lat, 'maxLat' => $row->lat, 'minLng' => $row->lng, 'maxLng' => $row->lng);
             } else {
                 if ($row->lat < $prefectureLocation[$prefecture]['minLat']) {
                     $prefectureLocation[$prefecture]['minLat'] = $row->lat;
                 }
                 if ($row->lat > $prefectureLocation[$prefecture]['maxLat']) {
                     $prefectureLocation[$prefecture]['maxLat'] = $row->lat;
                 }
                 if ($row->lng < $prefectureLocation[$prefecture]['minLng']) {
                     $prefectureLocation[$prefecture]['minLng'] = $row->lng;
                 }
                 if ($row->lng > $prefectureLocation[$prefecture]['maxLng']) {
                     $prefectureLocation[$prefecture]['maxLng'] = $row->lng;
                 }
             }
         }
     }
     $varExport = var_export($prefectureLocation, true);
     echo str_replace('  ', "\t", $varExport);
     echo "\n";
 }