Example #1
0
 function process()
 {
     if (!isset($this->gpx) || !file_exists($this->gpx)) {
         $this->_err[] = "no gpx file input";
         return false;
     }
     $xml = simplexml_load_file($this->gpx);
     $arr = obj2array($xml);
     // 1. 取得 bounds, 轉換成 twd67 最近的 bounds
     //list($x,$y,$x1,$y1) = $this->get_bound($arr);
     list($x, $y, $x1, $y1) = $this->get_bbox(file_get_contents($this->gpx));
     if ($this->taiwan == 0) {
         $this->_err[] = "超出台澎範圍或檔案剖析有誤,請回報";
         return false;
     }
     if ($this->taiwan == 1) {
         list($tx, $ty) = proj_geto672(array($x, $y));
         list($tx1, $ty1) = proj_geto672(array($x1, $y1));
     } else {
         list($tx, $ty) = proj_geto672_ph(array($x, $y));
         list($tx1, $ty1) = proj_geto672_ph(array($x1, $y1));
     }
     // 若是自動 get_bound 的話  多 expend 一格
     if (isset($this->input_bound67['x'])) {
         // 免算
         $tl = array($this->input_bound67['x'], $this->input_bound67['y']);
         $br = array($this->input_bound67['x1'], $this->input_bound67['y1']);
     } else {
         // 如果需要多 index 的話, 才 expend
         // 並且不是範圍已經輸入了
         if ($this->show_label_wpt == 1) {
             $expend = 1000;
         } else {
             $expend = 0;
         }
         /* 四邊都 expend
         $tl = array( floor($tx / 1000)*1000 - $expend, ceil($ty / 1000)*1000 + $expend);
         $br = array( ceil($tx1 / 1000)*1000 + $expend, floor($ty1 / 1000)*1000 - $expend);
          */
         // 只在右手邊 expend
         $tl = array(floor($tx / 1000) * 1000, ceil($ty / 1000) * 1000);
         $br = array(ceil($tx1 / 1000) * 1000 + $expend, floor($ty1 / 1000) * 1000);
         if ($this->do_fit_a4 == 1) {
             list($tl, $br) = $this->fit_a4($tl, $br);
         }
     }
     // 檢查一下是不是太大範圍
     if ($br[0] - $tl[0] >= $this->limit['km_x'] || $tl[1] - $br[1] >= $this->limit['km_y']) {
         $this->_err[] = sprintf("超出範圍: x=%d y=%d (請刪除不需要之航跡)", $br[0] - $tl[0], $tl[1] - $br[1]);
         return false;
     }
     // 計算字型比例 依照若是標準地圖產生器出圖, 18px (1km 315px)
     $this->fontsize = intval(18 * ($this->width / (($br[0] - $tl[0]) / 1000) / 315));
     // 若是產生縮圖
     if ($this->fontsize < $this->default_fontsize) {
         $this->fontsize = $this->default_fontsize;
     }
     // 存入 bounds
     $this->bound_twd67 = array("tl" => $tl, "br" => $br, "ph" => $this->taiwan == 2 ? 1 : 0);
     if ($this->taiwan == 1) {
         $this->bound = array("tl" => proj_67toge2($tl), "br" => proj_67toge2($br));
     } else {
         $this->bound = array("tl" => proj_67toge2_ph($tl), "br" => proj_67toge2_ph($br));
     }
     // 計算比例
     $this->ratio['x'] = $this->width / ($this->bound['br'][0] - $this->bound['tl'][0]);
     // 經緯度比例這樣會出錯
     //$this->height = round(($this->bound['tl'][1] - $this->bound['br'][1])*$this->ratio);
     $this->height = ($tl[1] - $br[1]) / 1000 * 315;
     $this->ratio['y'] = $this->height / ($this->bound['tl'][1] - $this->bound['br'][1]);
     // 2. 取得所有 trk point 的高度 作為 colorize trk 的依據
     // $this->dump();
     // 像 oruxmap 會產生只有一層的 trk, 而不會有 trk 的 array => 為了不想重寫 parser, 放到 array 去
     if (isset($arr['trk']['trkseg'])) {
         $arr['trk'][0] = $arr['trk'];
     }
     // 共有多少 tracks?
     $total_tracks = count($arr['trk']);
     $min = 8000;
     $max = 0;
     for ($i = 0; $i < $total_tracks; $i++) {
         if (!isset($arr['trk'][$i]['name'])) {
             // skip track without "name"
             // echo "no name:" . var_dump($arr['trk']);
             continue;
         }
         $this->track[$i] = array("name" => $arr['trk'][$i]['name']);
         $j = 0;
         foreach ($arr['trk'][$i]['trkseg']['trkseg'] as $trk_point) {
             // skip route/track without '@attributes'
             // echo "get point:";
             // print_r($trk_point);
             if (!isset($trk_point['@attributes']['lon'])) {
                 if (!isset($trk_point['trkpt']['lon'])) {
                     continue;
                 } else {
                     $trk_point['@attributes']['lon'] = $trk_point['trkpt']['lon'];
                     $trk_point['@attributes']['lat'] = $trk_point['trkpt']['lat'];
                 }
             }
             if ($trk_point['@attributes']['lon'] > $this->bound['br'][0] || $trk_point['@attributes']['lon'] < $this->bound['tl'][0] || $trk_point['@attributes']['lat'] > $this->bound['tl'][1] || $trk_point['@attributes']['lat'] < $this->bound['br'][1]) {
                 // echo "oob!!!!!\n";
                 continue;
             }
             if (isset($trk_point['ele'])) {
                 // 如果高度小於 0
                 if ($trk_point['ele'] < 0) {
                     $trk_point['ele'] = 0;
                     $arr['trk'][$i]['trkseg']['trkseg']['ele'] = 0;
                 }
                 if ($trk_point['ele'] < $min) {
                     $min = $trk_point['ele'];
                 } else {
                     if ($trk_point['ele'] > $max) {
                         $max = $trk_point['ele'];
                     }
                 }
             } else {
                 $trk_point['ele'] = -100;
             }
             $this->track[$i]['point'][$j] = $trk_point;
             $this->track[$i]['point'][$j]['rel'] = $this->rel_px($trk_point['@attributes']['lon'], $trk_point['@attributes']['lat']);
             $j++;
         }
         // 處理 track 的高度
     }
     $this->ele_bound = array($min, $max);
     //$this->dump();
     //$this->waypoint = $arr['wpt'];
     $j = 0;
     if (isset($arr['wpt'])) {
         foreach ($arr['wpt'] as $waypoint) {
             if ($waypoint['@attributes']['lon'] > $this->bound['br'][0] || $waypoint['@attributes']['lon'] < $this->bound['tl'][0] || $waypoint['@attributes']['lat'] > $this->bound['tl'][1] || $waypoint['@attributes']['lat'] < $this->bound['br'][1]) {
                 continue;
             }
             $this->waypoint[$j] = $waypoint;
             $this->waypoint[$j]['rel'] = $this->rel_px($waypoint['@attributes']['lon'], $waypoint['@attributes']['lat']);
             if ($this->taiwan == 1) {
                 $this->waypoint[$j]['tw67'] = proj_geto672(array($waypoint['@attributes']['lon'], $waypoint['@attributes']['lat']));
             } else {
                 $this->waypoint[$j]['tw67'] = proj_geto672_ph(array($waypoint['@attributes']['lon'], $waypoint['@attributes']['lat']));
             }
             $j++;
         }
     }
     unset($arr);
     //$this->dump();
     return true;
 }
Example #2
0
 /**
  * transcoord 
  * 四座標
  * @param mixed $p1 
  * @param mixed $p2 
  * @param mixed $p3 
  * @param mixed $p4 
  * @access public
  * @return void
  */
 function transcoord($p1, $p2, $p3, $p4)
 {
     $r = array();
     if ($this->ph == 1) {
         list($r['W'], $r['N']) = ph_proj_67toge2($p1);
         list($r['E'], $r['S']) = ph_proj_67toge2($p2);
         list($r['E1'], $r['N1']) = ph_proj_67toge2($p3);
         list($r['W1'], $r['S1']) = ph_proj_67toge2($p4);
     } else {
         list($r['W'], $r['N']) = proj_67toge2($p1);
         list($r['E'], $r['S']) = proj_67toge2($p2);
         list($r['E1'], $r['N1']) = proj_67toge2($p3);
         list($r['W1'], $r['S1']) = proj_67toge2($p4);
     }
     return $r;
 }
Example #3
0
function Demo_TW()
{
    $p = array(282745, 2641869);
    print_r($p);
    echo "cs2cs法:\n";
    $p1 = cs2cs_t67to97($p[0], $p[1], 0);
    print_r($p1);
    echo "cs2cs法 invert:\n";
    $pp = cs2cs_t97to67($p1[0], $p1[1], 0);
    print_r($pp);
    echo "平面四參數轉換:\n";
    $p1 = t67to97($p[0], $p[1]);
    print_r($p1);
    echo "平面四參數轉換 Invert:\n";
    $p2 = t97to67($p1[0], $p1[1]);
    print_r($p2);
    echo "使用平面四參數轉換:\n";
    $q = proj_67toge($p);
    print_r($q);
    echo "使用 cs2cs:\n";
    $q1 = proj_67toge2($p);
    print_r($q);
}
Example #4
0
/**
 * img_from_tiles 
 * 
 * @param mixed $base_dir 
 * @param mixed $x 
 * @param mixed $y 
 * @param mixed $shiftx 
 * @param mixed $shifty 
 * @param mixed $zoom 
 * @param int $ph 
 * @param int $debug 
 * @param string $tmpdir 
 * @param int $warm  => 1 表示不產生 /dev/shm 檔案, 2 表示 reload cache
 * @access public
 * @return void
 */
function img_from_tiles($base_dir, $x, $y, $shiftx, $shifty, $zoom, $ph = 0, $debug = 0, $tmpdir = "/dev/shm", $cache_dir = "/mnt/twmapcache/cache", $warm = 0)
{
    //$cache_dir = "/mnt/twmapcache/cache";
    $montage_bin = "montage";
    $cache_filename = "";
    // 如果是 1x1
    if ($shiftx == 1 && $shifty == 1) {
        $cache_filename = sprintf("%s/%d/%s/%d/%d_%d.png", $cache_dir, $zoom, $ph ? "ph" : "tw", $x / 1000, $x / 1000, $y / 1000);
        if (file_exists($cache_filename) && $warm != 2) {
            $outimage = tempnam($tmpdir, "MTILES");
            if (!$warm) {
                // 選擇 copy 或者 symlink
                //copy($cache_filename,$outimage);
                unlink($outimage);
                symlink($cache_filename, $outimage);
            }
            if ($debug) {
                $msg = sprintf("cache: {$cache_filename} read %s", is_link($cache_filename) ? "[link]" : "");
                if ($warm > 0) {
                    echo "{$msg}\n";
                } else {
                    error_log($msg);
                }
            }
            return array(TRUE, $outimage, "cached: {$cache_filename}");
        }
    }
    // 左上
    $dir = $base_dir . "/" . $zoom;
    @mkdir($dir, 0755, true);
    // 右下
    $x1 = $x + $shiftx * 1000;
    $y1 = $y - $shifty * 1000;
    if ($debug) {
        error_log("img_from_tiles({$base_dir}, {$x}, {$y}, {$shiftx}, {$shifty}, {$zoom},{$ph}, {$debug}); \n");
    }
    if ($ph == 0) {
        // 台灣本島 proj_67toge2 使用 cs2cs 把 67 轉 97
        list($tl_lon, $tl_lat) = proj_67toge2(array($x, $y));
        $a = LatLong2XYZ($tl_lon, $tl_lat, $zoom);
        list($br_lon, $br_lat) = proj_67toge2(array($x1, $y1));
        $b = LatLong2XYZ($br_lon, $br_lat, $zoom);
    } else {
        list($tl_lon, $tl_lat) = ph_proj_67toge2(array($x, $y));
        $a = LatLong2XYZ($tl_lon, $tl_lat, $zoom);
        list($br_lon, $br_lat) = ph_proj_67toge2(array($x1, $y1));
        $b = LatLong2XYZ($br_lon, $br_lat, $zoom);
    }
    if ($debug) {
        error_log("x={$x} y={$y} x1={$x1} y1={$y1} tl={$tl_lon},{$tl_lat} br={$br_lon},{$br_lat}");
        error_log("a=" . print_r($a, true) . " b=" . print_r($b, true));
    }
    $xx = $b[0] - $a[0] + 1;
    $yy = $b[1] - $a[1] + 1;
    // 先偷抓一次看看
    for ($j = $a[1]; $j <= $b[1]; $j++) {
        for ($i = $a[0]; $i <= $b[0]; $i++) {
            $imgname = sprintf("%d_%d.png", $i, $j);
            if (!file_exists("{$dir}/{$imgname}")) {
                // create tile cache from Internet
                exec(sprintf("wget -q -O %s 'http://rs.happyman.idv.tw/map/tw25k2001/zxy/{$zoom}_{$i}_{$j}.png'", "{$dir}/{$imgname}"));
            }
        }
    }
    $img = array();
    for ($j = $a[1]; $j <= $b[1]; $j++) {
        for ($i = $a[0]; $i <= $b[0]; $i++) {
            $imgname = sprintf("%d_%d.png", $i, $j);
            if (file_exists("{$dir}/{$imgname}") && !is_link("{$dir}/{$imgname}")) {
                if ($debug) {
                    error_log("{$dir}/{$imgname} ok " . filesize("{$dir}/{$imgname}"));
                }
                $img[] = $imgname;
            } else {
                if ($debug) {
                    error_log("{$dir}/{$imgname} not exist");
                }
                return array(FALSE, "超出圖資範圍", false);
            }
        }
    }
    if ($debug) {
        //	error_log(print_r($img, true));
        error_log(print_r("{$xx} x {$yy}", true));
    }
    // 左上點所在的 tile,
    $rect = getLatLonXYZ($a[0], $a[1], $zoom);
    if ($debug) {
        error_log("getLatLonXYZ({$a['0']},{$a['1']},{$zoom})");
        error_log(print_r($rect, true));
    }
    $rx = 256 / $rect->width;
    $ry = 256 / $rect->height;
    $px_shiftx = ($tl_lon - $rect->x) * $rx;
    if ($debug) {
        error_log(sprintf("tl y: %f rect->y %f\n", $tl_lat, $rect->y));
    }
    $px_shifty = 256 - ($tl_lat - $rect->y) * $ry;
    if ($debug) {
        error_log(sprintf("px_shiftx,y = %f %f\n", $px_shiftx, $px_shifty));
    }
    // 要取的範圍 width px
    $px_width = ($br_lon - $tl_lon) * $rx;
    $px_height = ($tl_lat - $br_lat) * $ry;
    if ($debug) {
        error_log(sprintf("px_width,y = %f %f\n", $px_width, $px_height));
    }
    // 拼圖
    $outimage = tempnam($tmpdir, "MTILES");
    $cmd = sprintf("cd %s; %s %s -mode Concatenate -tile %dx%d png:%s", $dir, $montage_bin, implode(" ", $img), $xx, $yy, $outimage);
    if ($debug) {
        error_log("cmd=" . $cmd);
    }
    exec($cmd, $out, $ret);
    if ($debug) {
        error_log("ret=" . implode("", $out));
    }
    if ($ret != 0) {
        unlink($outimage);
        return array(FALSE, "err:" . $cmd . "ret=" . implode("", $out), false);
    }
    $cropimage = tempnam($tmpdir, "CTILES");
    $resize = sprintf("%dx%d\\!", 315 * $shiftx, 315 * $shifty);
    if ($ph == 0 && $tl_lon > 121 || $ph == 1 && $tl_lon > 119) {
        $rotate_angle = "-0.3";
        $offset_x = 0;
        $offset_y = 2;
        // equals to `affline_rotate $rotate_angle`
        $affine = "0.999986,-0.005236,0.005236,0.999986,0.000000,0.000000";
    } else {
        $rotate_angle = "0.3";
        $offset_x = 2;
        $offset_y = 0;
        $affine = "0.999986,0.005236,-0.005236,0.999986,0.000000,0.000000";
    }
    //$afrotate = realpath(dirname(__FILE__)) . "/affine_rotate";
    $cmd = sprintf("convert %s -matte -virtual-pixel Transparent \\\n\t\t-affine %s -transform +repage %s", $outimage, $affine, $outimage);
    exec($cmd, $out, $ret);
    if ($debug) {
        error_log($cmd);
    }
    //$cmd=sprintf("convert %s -crop %dx%d+%d+%d -adaptive-resize %s -contrast-stretch 1x1%% -sharpen 1.5x1.5 miff:- | composite -gravity northeast %s - png:%s",$outimage,
    $cmd = sprintf("convert %s -crop %dx%d+%d+%d -adaptive-resize %s -contrast-stretch 1x1%% -sharpen 1.5x1.5 png:%s", $outimage, ceil($px_width), ceil($px_height), round($px_shiftx) + $offset_x, round($px_shifty) + $offset_y, $resize, $cropimage);
    if ($debug) {
        error_log("cmd=" . $cmd);
    }
    exec($cmd, $out, $ret);
    unlink($outimage);
    if ($ret == 0) {
        // 1x1 則 cache
        if (!empty($cache_filename)) {
            @mkdir(dirname($cache_filename), 0755, true);
            copy($cropimage, $cache_filename);
        }
        if ($debug) {
            error_log("cache: {$cache_filename} created");
        }
        return array(TRUE, $cropimage, "made");
    } else {
        unlink($cropimage);
        return array(FALSE, "err:" . $cmd . "ret=" . implode("", $out), false);
    }
}