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; }
function img_from_tiles_lonlat($base_dir, $tl_lon, $tl_lat, $br_lon, $br_lat, $zoom, $ph = 0, $debug = 0, $tmpdir = "/dev/shm") { // 左上 $dir = $base_dir . "/" . $zoom; // 右下 //$x1 = $x + $shiftx * 1000; //$y1 = $y - $shifty * 1000; $v3image = "imgs/v3.png"; if ($debug) { error_log("img_from_tiles_lonlat({$base_dir}, \${$tl_lon}, {$tl_lat}, {$br_lon}, {$br_lat}, {$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); list($x, $y) = proj_geto672(array($tl_lon, $tl_lat)); list($x1, $y1) = proj_geto672(array($br_lon, $br_lat)); } 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); list($x, $y) = ph_proj_geto672(array($tl_lon, $tl_lat)); list($x1, $y1) = ph_proj_geto672(array($br_lon, $br_lat)); } $shiftx = ($x1 - $x) / 1000; $shifty = ($y - $y1) / 1000; 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}")) { exec("wget -q -O /dev/null 'http://rs.happyman.idv.tw/map/tw25k2001/zxy/16_{$i_}{$j}.png'"); } } } $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}")) { if ($debug) { error_log("{$dir}/{$imgname} ok"); } $img[] = $imgname; } else { if ($debug) { error_log("{$dir}/{$imgname} not exist"); } return array(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; montage %s -mode Concatenate -tile %dx%d png:%s", $dir, implode(" ", $img), $xx, $yy, $outimage); if ($debug) { error_log("cmd=" . $cmd); } exec($cmd, $out, $ret); if ($ret != 0) { return array(FALSE, "err:" . $cmd); } $cropimage = tempnam($tmpdir, "CTILES"); $resize = sprintf("-adaptive-resize %dx%d\\!", 315 * $shiftx, 315 * $shifty); // $resize = ""; $cmd = sprintf("convert %s -crop %dx%d+%d+%d %s -contrast-stretch 1x1%% -sharpen 1.5x1.5 miff:- | composite -compose bumpmap -gravity northeast %s - png:%s", $outimage, ceil($px_width), ceil($px_height), round($px_shiftx), round($px_shifty), $resize, $v3image, $cropimage); if ($debug) { error_log("cmd=" . $cmd); } exec($cmd, $out, $ret); unlink($outimage); if ($ret == 0) { return array(TRUE, $cropimage); } else { return array(FALSE, "err:" . $cmd); } }