2014年8月25日 星期一

OSM 混搭很簡單:製作你自己的分店/行事曆/造勢活動總覽/... 「網頁內嵌互動地圖」

用 OSM 做的 「全球機場位置及代號」 地圖 [2015/3/18: 改推薦 我的私房地圖, OSM 版, 直接滑鼠編輯, 連程式碼都不用寫!]

你的社群/公司/市政府/... 有沒有一些值得用互動地圖呈現的公開資料, 但是以前一直覺得程式設計門檻太高?

  1. 本連鎖店在哪些地方有分店?
  2. 本市各個腳踏車租借點還剩幾部車、 幾個空位?
  3. 哪位參選人或哪個政黨的所有候選人何時在哪裡有官方辦的或支持者辦的造勢活動?
  4. Cosplay 社群近期將在哪些地方舉辦活動?
  5. 全臺灣有哪些學校在電腦教室內安裝 linux?
  6. ...

貴哥沒什麼機會寫大程式; 我的專長是把看似困難的問題 -- 例如製作互動地圖 -- 用很短的程式碼解決。 真的, 你們社群/公司/政黨/... 其實也辦得到! 第一, 需要有一份 [文字瀏覽器可以看得見的] 網頁, 上面蒐集了充份的原始文字資訊 (經緯度座標、 學校/活動/分店的名稱 and/or 超連結、 ...), 格式不拘。 (下詳) 第二, 要找得到一位略通 php 跟 javascript 網頁程式設計的電腦咖, 有能力在參考完四個範例之後, 可以自行修改三百多列的程式當中的四十列左右。 然後你們就可以在自己的網頁上秀出含有這些文字資訊的互動地圖了! 還有 行銷咖請先別走! 請先讀一下第一節, 因為你比電腦咖更懂得想像有哪些有利於社群/公司/政黨/...宣傳的可能性。 特別呼叫 g0v 的朋友: 歡迎拿 g0v 已經蒐集的此類文字資料挖小坑給貴哥跳 :-)

一、 可以拿來做出什麼效果?

(這一節, 行銷咖必讀。)

OpenStreetMap 不僅僅是一個 可以裝在手機上的離線地圖, 它也可以是你們社群/公司/政黨/學校/... 的行銷工具。 不廢話, 請先看看貴哥拿 「胡亂搜尋來的文字網頁」 所做出來的四個例子:

  1. 全球機場位置及代號; 文字資料來源: The Global Airport Database 因為這個例子資料量太大, 所以 airports.json 資料檔只保留臺灣的機場。 (初學者請忽略: 完整原始資料放在 airports.csv , 可以用 perl 小程式 airports.txt 轉成 airports.json。)
  2. 世界各國首都; 文字資料來源: All countries and their capitals with Coordinates
  3. 1900 年以來, 規模 8 以上的地震; 文字資料來源: Magnitude 8 and Greater Earthquakes Since 1900
  4. 澳洲雪梨市鬼屋地圖; 文字資料來源: Haunted Locations of Sydney

重點就是要有 文字網頁, 裡面要包含 經緯度座標。 排列方式任意, (從原始碼) 看得出規律就好。 不僅是前三個 「以表格或試算表方式呈現」 的例子處理起來很簡單; 就算遇到像第四個例子 (鬼屋地圖) 那樣子一帖一帖留言的格式, 程式也不會複雜太多。

「但是我只有街道名稱/門牌號碼, 沒有經緯度座標耶... 怎麼辦呢?」 那就更應該趕快把 osmand 下載到你的手機囉! 只要 在 osmand 地圖上你有興趣的地點長按一下 就會出現當地的經緯度座標。 或者也可以 用 google maps 查經緯度。 又, 李小淮分享了一個 輸入地址批次轉換經緯度小工具

如果你心目中想要建立的地圖, 需要一些目前手邊沒有的資訊, 也可考慮採用 wiki 共筆的方式, 借社群的力量共同完成。

以下是給電腦咖看的。

二、 製作步驟

請下載上面四個範例程式的打包檔 [ 程式 + 資料] 回去研究。 以下假設你拿 「強震地圖」 作為修改的出發點。

  1. 跟行銷咖討論, 設計出原始文字網頁資料的格式 (記得, 可以是 wiki 頁面!) 然後用 wget 把它抓回你的 linux 電腦: wget -O /tmp/earthquakes.htm http://earthquake.usgs.gov/earthquakes/eqarchives/year/mag8/magnitude8_1900_date.php
  2. earthquakes.txt 這個小小的 php 程式去修改, 用它處理上述文字網頁資料、 產生 json 格式的資料檔: php earthquakes.txt /tmp/earthquakes.htm > earthquakes.json 如果資料會更新的話, 以後這件事可以寫入 cron job, 每天或每小時更新一次資料之類的, 或是做一個 「把資料更新至地圖上」 的連結, 讓資料輸入人員按。 程式為什麼可以這麼短!? 要感謝 QueryPath 讓我們可以用 css selectors 語法簡便地抓出重點欄位。
  3. 小幅修改網頁檔 earthquakes.html
  4. 小心修改程式檔 earthquakes.js

用 vim 比較兩支程式的差異, 就知道有哪些地方需要改。 其中最大的工程就是修改 .js 程式檔。 可是貴哥很懶惰, 不想逐一解釋。 沒關係, 我發明了一個懶人程式設計教學法: 我寫了上述四個範例, 你可以拿其中兩兩出來比對差異, 就知道有哪些地方需要改。 例如我用 vimdiff earthquakes.js capitals.js 可以比較 「強震」 跟 「首都」 兩張圖的程式修改了哪些地方。 (其中有很多地方其實只是把變數的名字換得更符合主題而已。)

三、 一些心得與提醒

其實我對 javascript 很不熟; php 也勉強而已。 以下是一些心得提醒; 如果有讀者留言提出重要的問題, 我也會再把更多提醒補在這裡。

  1. 把 「分析文字網頁資料」 跟 「畫地圖」 兩件事拆開來, 邏輯跟除錯都變得比較簡單。
  2. 自己寫程式產生 .json 檔很容易出錯、 很難 debug。 php 有 json_encode() 函數; perl 有 JSON 模組 (請見 「全球機場位置及代號」 的例子) 除錯快多了。
  3. 一定要打開 firebug 的 console, 用 console.log() 除錯。
  4. OpenStreetMap 畫地圖的函式庫叫做 OpenLayers, 文件很豐富。 遇到看不懂的函數呼叫, 請先用函數名稱 (例如 OpenLayers.LonLat.transform 或 OpenLayers.Feature.Vector) 搜尋。
  5. 根據 官方文件, 要建立 markers (就是那些地圖標記), 應該要用 vector layer 而不是用 (過時的) marker layer。
  6. 我搜尋參考了很多範例程式; 不過展現 marker 互動的部分, 最重要的參考範例是 Feature Events Example
  7. 有兩個東西看來很有趣但我已經沒力氣學: Overpass API 可以把 OSM 裡面的物件調出來; 如果想畫行政區塊 (國家範圍、 省/州範圍、 縣市範圍) 應該要研究一下 administrative boundary map (左下角 「Info & Contact」 連結, 進入該頁搜尋 「admin」)。

四、 請分享 & 歡迎求助

做出有趣的地圖了嗎? 請留言分享你的互動地圖網址吧。 包含商業或政黨的互動地圖網頁也都很歡迎哦! 也歡迎留下 google maps 混搭出來的互動地圖網址、 歡迎下技術戰帖/踢館哦!

自由軟體社群、 自由文化社群、 g0v、 ... 你們已有現成的經緯度文字資料檔想轉成互動地圖需要協助嗎? 我樂意幫忙哦。 (是說 g0v 高手很多, 應該輪不到我...)

貴校/貴社團有一群技術咖想上機實作教學嗎? 發 mail 邀請我演講吧 :-)

「具有公共意義、 可以幫助很多人」 的請求, 或是可以幫貴哥拼經濟的請求, 最容易獲得我的回應哦 ;-)

(本文接受科技部計畫補助: MOST-103-2221-E-492-028 「台灣開放街圖圖資平台建置與應用」)

沒有留言:

張貼留言

因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。