brandboat

Tyler says the things you own, end up owning you.

Bash Redirect : &>

1
unalias fs &> /dev/null

這指令是在看 hadoop 安裝指南 時注意到的,主要是第一次看到 &> 這樣的寫法感到好奇才特別去查。

之前曾經學過有關於 shell script 訊息導向(redirection)的部份,但看到的多是

1
2
3
4
5
// 1. stderr redirect to /dev/null
unalias fs 2> /dev/null 

// 2. stderr redirect to stdout
grep * 2>&1

這邊稍微解釋一下,1代表 standard output,2代表standard error。

而 &> 其實就是將 stderr 與 stdout 導向至檔案,其意思等同於

1
> file 2>&1

舉個例子,我們要將標題的指令中的所有訊息全部導向至 /dev/null 這個大黑洞,原本要打

1
unalias fs > /dev/null 2>&1

現在只要換成

1
unalias fs &> /dev/null

或者

1
unalias fs >& /dev/null

但這樣簡便的寫法只有在 bash 可以用,csh,tcsh,sh 則沒有。

梅竹黑客松

交大黑客松有別於去年,今年似乎是與清大一起合辦,整體資源都比去年還要更加豐富,表現更加亮眼。其實去年最不滿意的也就只有餐點真的不太好,”便當 Buffet” ,老實說我都不太吃,等到點心時段衝上去搶餅乾刺激多了!今年一整個大翻盤,buffet很澎湃,至少連像我這樣對飲食挑剔的人聽到餐點時段都願意放下手邊的程式碼跑下去大吃一頓,很多參加的朋友也說吃的很開心,本來黑客松就是要這樣嘛!吃飽Coding,Coding飽吃,不得不說才舉辦第2年就有這樣的表現,主辦單位表現不俗。

今年還有令一個很大的好處就是不再是每一組都要上台DEMO,這樣實在太花時間。今年可能因為隊伍數較多,是由各個企業分別選出該類別前2名上台DEMO,時間上就節省很多。另外,梅竹黑客松,不像其他黑客松幾乎都是只有一個主題,全部隊伍選出前3名,以及幾組佳作,他們會先讓各組選自己適合的類別,比如我們這組覺得 Windows Azure 的題目較適合我們,那我們被分配到那組之後,就是與同樣都是那類別的人競爭,一個類別還沒有超過10組的,老實說機會很大。(雖然我們還是沒得名…)

話說去年我們真的啥都不會,糊裡糊塗就被分到博晶醫電,很訝異看到居然是jserv負責這項組別,他提到目前裝置沒有 Android 版本的 APP,於是我們小組便試著去幫他們開發,但重點來了!我們這組根本沒有人會寫 App,勉強要說我也才學一個月,根本就跟初心者沒兩樣,一般人大概會覺得很不可思議,怎麼會用自己最不擅長的東西去開發產品?特別又在時間最為緊迫的黑客松?但老實說我們什麼都不精,自然而然也就沒有時間下去想這些,只覺得這樣的想法很不錯,最後不管三七二十一還是栽下去了。好在最後至少可以把心電圖轉在手機上呈現,可惜的是我們在DEMO時插錯投影機接頭,DEMO失敗…。不過 jserv 很欣賞我們的表現,最後仍給我們第三名的成績,本來我們隊名就叫作 GGZMain,就是想北上見見世面罷了,怎樣丟臉都不在乎,但 jserv 給我們這樣的獎項老實說心裡感動不少,又給我們一個動力繼續前進!

今年就不一樣了,算是事前就有規劃好題目,有稍微做一點作業,我們題目是做一個校園腳特車擁擠程度即時系統,主要就是讓正在使用此 APP 的學生看到附近的腳踏車車位是否過於壅塞,並且給一個壅塞指數評分,這樣子要上課的學生就知道要避免去停在那些過於壅塞的地方,讓每個人都可以快速找到車位。雖然沒有受到評審青睞,但至少DEMO成功!畢竟我們GKZMain(見過世面)!XDD

兩年比較下來我認為隊伍水平是去年較高,UI/UX 也是去年較為優秀,創新程度的話或許今年表現好一些,但趣味程度…去年做馬總統 Schedule 追蹤系統讓我笑到半死,到現在我還是覺得他們有趣的多!今年自己最喜歡的是Project jəmp,由於最近大家都喜歡跳到半空中拍照,但捕捉但瞬間不太容易,他們就應用的迪英加科技所提供的設備去偵測跳到最高點的時間讓手機自動按下快門。這idea真的超棒,我覺得根本就可以出去開公司了吧?!也難怪他們最後拿到進入 NTU Hackathon 的入場卷,厲害!

我是成大生,老實說很羨慕台清交都有這樣的活動,閉幕的時候聽到台大霸氣的說出今年預估招到 800 人,並且會招攬國外隊伍,震驚到說不出話來,雖說這幾所大學資源或許比我們豐富,但差異如此之大還是太令人訝異。號稱南霸天的我們,也不能辜負這名號阿!每年自己北上參加黑客松都在感慨,花了這一頓車錢,就是想看看同年紀的大學生究竟可以做到怎樣的程度,畢竟南北有別,成大風氣趨向保守,如果可以,很希望為成大注入一股熱血,據聞系上有老師也希望可以舉辦黑客松,已經開始招兵買馬籌畫流程。也讓自己想到或許我們可以借鏡梅竹黑克松的經驗,讓南部學生也有自己的黑客松!

Chrome 標籤亂碼

Ubuntu 解決辦法如下:

sudo vim /etc/fonts/conf.d/49-sansserif.conf 內容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!--
If the font still has no generic name, add sans-serif
-->
  <match target="pattern">
    <test qual="all" name="family" compare="not_eq">
      <string>sans-serif</string>
    </test>
    <test qual="all" name="family" compare="not_eq">
      <string>serif</string>
    </test>
    <test qual="all" name="family" compare="not_eq">
      <string>monospace</string>
    </test>
    <edit name="family" mode="append_last">
      <string>sans-serif</string>
    </edit>
  </match>
</fontconfig>

1
2
3
<edit name="family" mode="append_last">
  <string>sans-serif</string>
</edit>

中的 sans-serif 改為你想要的中文字型,若不知道就填寫 Ubuntu

Routing on OpenStreetMap (Pgrouting)

Demo: http://routingonosm-brandboat.rhcloud.com/ github project: https://github.com/brandboat/Routing-On-OSM

這個 project 主要是利用 pgrouting 讓 openstreetmap 來做兩點最佳路徑規劃,像這類 routing project 其實已經是老生常談,大概 google 一下都能找到很類似的 project (OSM Routing),但是利用 pgrouting 的似乎不多,google找到相關技術整合的文章也是寥寥可數,我在這邊分享我如何利用 openstreetmap + pgrouting + nodejs 寫出一個簡單的 routing project,以及遇到的問題。

介紹

pgrouting 是一套基於 postgresql/postGIS 上的套件,他賦予 geospatial routing database routing 功能,postgresql 本身是與 MySQL 打對台的關聯式資料庫,但是 postGIS 這個套件讓 postgresql 特別去處理軌跡路線。所以要使用 pgrouting 裏頭的功能你必須先安裝 postgresql 以及 postGIS。

安裝

  • postgresql : sudo atp-get install postgresql-9.1 (Ubuntu) 當然要安裝別的版本(Ex. 9.3)都沒關係,重點是接下來要安裝的postGIS 一定要是 2.0 以上版本,否則你無法在 postgresql 使用 pgrouting 以及 osm2pgrouting,然而在 Ubuntu 底下當你使用 apt-get 安裝postgresql9.1 他預設使用 postGIS 1.5。所以你必須先移除postGIS(sudo apt-get remove --purge postgis)再自己在抓 postGIS 2.0 source code 下來自己安裝。

  • postGIS : 這邊我建議直接參考 本篇教學 ,因為 postGIS2.0 使用到很多套件都是 Ubuntu 套件管理中心沒有的,你得自己抓原始碼 compile。 (你還在用 sudo make install 嗎? 試試 sudo checkinstall,至於好處在哪? 直接使用你就知道了)

  • pgrouting : sudo apt-get install postgresql-9.1-pgrouting

  • osm2pgrouting : sudo apt-get install osm2pgrouting openstreetmap 直接下載的圖資沒辦法直接在pgrouting底下使用,你得先利用此套件轉換。

為了測試你到底有沒有安裝正確,先進入 database psql -U postgres or psql -U postgres -d postgres (-U: user -d:dbname) postgresql 預設建立一位使用者 postgres 以及一個同名資料庫 postgres 進入之後打: CREATE EXTENSION postgis; CREATE EXTENSION pgrouting; 如果沒有出現 error 那就沒問題了。如果出現 could not open extension control file "/usr/share/postgresql/9.1/extension/postgis.control": No such file or directory,這就是因為 postGIS 還是1.5版本。 接下來的使用 pgrouting 方式這邊就不再詳細說明,pgrouting 官方說明文件寫得很清楚


應用 (Routing On OpenStreetMap)

開發環境

  • OS : Ubuntu 12.04
  • nodejs : 0.11.0
  • postgresql : 9.1
  • postGIS : 2.0
  • pgrouting : 9.1(base on postgresql 9.1)

nodejs 套件

  • nodejs + pgrouting + openstreetmap : nodejs 使用 MVC 框架的方式有很多,我使用的是 express ,然後參考以下 project 的寫法 express4-bootstrap-starter,詳細 nodejs 過程我就不說明了,google 一下其實滿多基礎教學。

  • node-postgres : nodejs底下與 postgresql 整合的非常好的套件。

  • leaflet : An Open-Source JavaScript Library for Mobile-Friendly Interactive Maps
  • Semantic-UI : UI

如何使用本 project

  • 安裝好上述套件
  • 取得圖資
  • 將圖資 load 進 postgresql
1
2
3
4
5
osm2pgrouting -file "sampledata.osm" \
                          -conf "/usr/share/osm2pgrouting/mapconfig.xml" \
                          -dbname DBNAME \
                          -user USERNAMWE \
                          -clean
  • node server.js
  • 點擊 Begin 之後任意點擊地圖任何一點,再點 End 重複相同動作之後點選 Route.

重點 SQL 語法說明 (app/controllers/route.js)

進入database後,打\d就可以看到該database下的所有欄位。 以下是裝好 postgis pgrouting 並使用 osm2pgrouting 就會 自動幫你建立的欄位。

List of relations

Schema Name Type Owner
public classes table brandboat
public geography_columns view brandboat
public geometry_columns view brandboat
public nodes table brandboat
public raster_columns view brandboat
public raster_overviews view brandboat
public relation_ways table brandboat
public relations table brandboat
public spatial_ref_sys table brandboat
public types table brandboat
public way_tag table brandboat
public ways table brandboat
public ways_vertices_pgr table brandboat
public ways_vertices_pgr_id_seq sequence brandboat
  1. SELECT id FROM ways_vertices_pgr ORDER BY st_distance(the_geom, st_setsrid(st_makepoint(reqPoint[i].lng + "," + reqPoint[i].lat + "), 4326)) LIMIT 1; 取得地圖上離reqPoint[i]最近的路的其中一點

  2. WITH result AS (SELECT * FROM ways JOIN (SELECT seq, id1 AS node, id2 AS edge_id, cost, ROW_NUMBER() OVER (PARTITION BY 1) AS rank FROM pgr_dijkstra('SELECT gid AS id, source::integer, target::integer, length::double precision AS cost FROM ways'," + begin + ", " + end + ", false, false)) AS route ON ways.gid = route.edge_id ORDER BY rank) SELECT ST_AsEWKT(result.the_geom), name from result; 這段很長,我將他拆開來討論

  3. pgr_dijkstra('SELECT gid AS id, source::integer, target::integer, length::double precision AS cost FROM ways'," + begin + ", " + end + ", false, false) 這段是利用pgr_dijkstra來取得begin和end中的最短路徑。
  4. SELECT seq, id1 AS node, id2 AS edge_id, cost, ROW_NUMBER() OVER (PARTITION BY 1) AS rank FROM pgr_dijkstra......ORDER BY rank 本來我沒有加ROW_NUMBER() OVER (PARTITION BY 1) AS rank,但後來發現,pgrouting他所回傳的路徑並沒有按照順序,這是他的一大缺點…所以我必須額外幫他增加一個欄位來紀錄路徑順序,並按照順序排列。
  5. SELECT * FROM ways JOIN...ON ways.gid = route.edge_id 這段是因為,pgr_dijkstra,回傳的東西裡頭並沒有路徑軌跡點,只有他的id,所以必須再跟ways做join來取得路徑軌跡點
  6. WITH result AS...SELECT ST_AsEWKT(result.the_geom), name from result; 最後將所有得到的結果命為 result table,且因為其軌跡直為 linestring,為了再網頁中顯示,必須再將他轉為一般座標點,所以用 ST_AsEWKT 將 result 底下存linestring的欄位the_geom將其轉為一般座標點。

經驗談

我很喜歡 nodejs ,剛好專題可能需要用到 pgrouting ,想說當作練功,就試著整合看看,不過自己剛踏入 nodejs 領域,對於很多概念還不夠清晰,很多文件看一看都是一知半解,只能透過實作來了解其中原理,特別台灣在nodejs方面文件都只有新手教學,安裝,get post…等,很多進階實現方法還有概念,文件都不多,可能這個領域的人比較喜歡自幹吧!XDDD,相較於RoR,喜歡出來分享相關經驗的有些少。

pgrouting 特別是在他基於 database 之上,你可以透過 query 就直接使用 pgrouting 裏頭提供的功能,相當方便,雖然我知道 routing 很多人都依賴用 google api ,但 google 畢竟不是做慈善,很多東西到一定量之後就要收費,openstreetmap 加上 pgrouting 完全無限制,但是國內卻沒有任何文章分享,實在很可惜…在這邊寫一篇簡單的開發經歷,一方面希望能幫到往後會利用到相關整合的人,如有任何疏漏或者指教之處,麻煩您 email 至 brandboat@gmail.com

架設平台

疑難雜症

  1. psql -U postgres 無法使用 Solution :
  2. sudo -u postgres psql
  3. sudo vim /etc/postgresql/9.1/main/pg_hba.conf 更改 local all postgres trust local all all trust host all all 127.0.0.1/32 trust host all all ::1/128 trust

  4. 在使用 overpass api 時,我使用以下code取得資料後,使用 osm2pgrouting 將資料 load 進 postgresql,卻發現無法使用…,可能是少了某些重要資料吧,於是我就乖乖用原本 osm api 去拿圖資。

1
2
3
4
5
6
7
8
9
10
<!--視覺所及的路段-->
<osm-script output="osm" timeout="25">
  <query type="way">
    <has-kv k="highway"/>
    <bbox-query />
  </query>
  <print mode="body"/>
  <recurse type="down"/>
  <print mode="skeleton" order="quadtile" />
</osm-script>

這使得我把其他不相關路的資訊也被迫load進圖資裡頭,使得最短路徑受到干擾, ex.橫跨路中央的橋就會讓結果受到干擾。(待解決)

參考 : http://workshop.pgrouting.org/ https://github.com/aredo/express4-bootstrap-starter/blob/master/app%2Fconfig%2Fexpress.js https://www.openshift.com/blogs/add-map-navigation-to-your-app-with-pgrouting-on-openshift https://www.openshift.com/blogs/instant-mapping-applications-with-postgis-and-nodejs

Vim 設置 Colorscheme

vim-railscasts-theme

  • cd ~/.vim/colors 若無此資料夾,請自行新建

  • vim railscasts.vim 複製 vim-railscasts-theme 中的 railscasts.vim 到裡頭

  • vim ~/.vimrc 加入此行 colorscheme railscasts 或者 colo railscasts 來設置 colorscheme



(圖片來源自:http://sunaku.github.io/vim-256color-bce-xterm.png)

如果使用了colorscheme而在tmuxvim時出現每一行底色跟背景顏色不一致的情況,這是因為設置了TERM=xterm-256color而衍生出來的問題,解決辦法 : disable Background Color Erase

  • ~/.vimrc中加入

set t_ut=