2014/08/11

[google-places-api-nearby-bus_station] 如何用 Google Places API 取得附近公車站

http://stackoverflow.com/questions/9340800/detect-the-nearest-transit-stop-from-the-given-location

有人問說如何在一個給定的位址(或經緯度)抓取附近的公車站。解答者雖然能用google-place-api取得bus_station,但無法取得公車編號(bus service No, bus stop ID)。 其實仔細爬google place details,連到url還是可能抓到公車編號。
以下是python pseudocode,更詳細作法在https://github.com/MikimotoH/gisTools/blob/master/google_place.py


#!/usr/bin/env python3

def nearby_bus_stations(lat, lng, apikey=""):
    """ Return a list of nearby bus stations around the location
    Args:
        lat: (float) latitude in degrees
        lng: (float) longitude in degrees
        apikey: Google API Key which enables Place API
    Yields:
        tuple(station:str, latitude: float, longitude: float, list[bus: string])
    Example:
        >>> sts = list(nearby_bus_stations(25.021072,121.551788))
        >>> print sts[0]
        ("黎明社教中心", 25.019798, 121.551818, ["懷恩專車S32"])
    """
    places = get_web_json(
        'https://maps.googleapis.com/maps/api/place/nearbysearch/json?' +
        'key=%s&location=%f,%f' % (apikey, lat, lng) +
        '&rankby=distance&language=zh-TW&types=bus_station')
    if places['status'] == 'OK':
        for result in places['results']:
            placeid = result['place_id']
            detail = get_web_json(
                'https://maps.googleapis.com/maps/api/place/details/' +
                'json?key=%s&placeid=%s' % (apikey, placeid) +
                '&language=zh-TW')
            station = detail['result']['name']
            loc = detail['result']['geometry']['location']
            buspage = get_webpage(detail['result']['url'])
            tree = lxml.html.document_fromstring(buspage)
            bus_elm = tree.xpath("/html/body/div[1]/div/div[4]/div[4]/div/div/div[2]/div/div[2]/div[1]/div[2]/div/div/div[2]/div/table/tr/td")[0]
            buses = list(filter(lambda s: len(s.strip()) > 0,
                                bus_elm.text_content().strip().split()))
            yield (station, float(loc['lat']), float(loc['lat']), buses)


2014/06/25

[urusei-yatsura-129]うる星やつら スケ番3人組 しゅがあ じんじゃあ ぺっぱあ 宇宙刑事の変身

福星小子TV第129集的作畫監督是「土器手司」,是我最喜愛的作畫監督之一(另一個是森山雄治)。
這集是內藏了「宇宙刑事」變身的梗。 劇情大意是拉姆的中二學妹三人組Ginger、Pepper、Sugar又要挑戰她們的學姊拉姆了,但正逢拉姆被諸星當的花心搞得脾氣最暴躁的一天,當然下場是很慘的。

 Ginger-Gavan


Pepper-Shaider


Sugar - Sharivan



[LiveBusTile]台北巴士快速磚

初衷

WP8上的公車App不好用! 我最常用的是「公車動態查詢」,雖然他可以pin-up許多secondary tile,但是secondary tile上無法顯示公車要來的時間。再者,他無法把兩個巴士時間並列比較在同一螢幕。

比如說,我要上班時可以選擇「『橘2』在秀山國小」或「『275』在秀景里」,但是這兩個站牌在不同位置,相隔步程在10分鐘以上。我一出門時就必須選擇是要往左走選「橘2」亦或往右走選「275」。我一旦選錯公車,就必定會錯過另一輛公車。

如果能像下圖一樣,把我上班時可以要搭的「橘2」與「275」並列比較,這樣我上班時才不會選錯公車而遲到。

程式設計

雖然我很久以前是寫WindowsMobile,但在WP8是完全新手。很大的功夫都是在鑽研GUI如何寫、xaml的語法、搞清楚MVVM架構不然公車時間無法更新。

再者,WP8對於背景更新動態磚有很多限制。雖然我用Facebook App知道他可以更新動態磚,但是WP8限制Background Agent的執行頻率是30分鐘。我無法調整成每60秒更新一次動態磚。目前還在尋找解決方法。

最後,我發覺我自己在開發機器上裝的Release版App,與上架之後從微軟官方市集下載來的App兩者的行為似乎有所不一致。我推薦給其他朋友(用WP的朋友好少哦)他們說的一些issue我沒辦法reproduce。程式人員注定要被「Works on my machine」給詛咒。

原始碼網頁

https://github.com/MikimotoH/LiveBusTile/tree/ListOfBusList

WindowsPhone App下載網頁

http://www.windowsphone.com/zh-tw/store/app/%E5%8F%B0%E5%8C%97%E5%B7%B4%E5%A3%AB%E5%BF%AB%E9%80%9F%E7%A3%9A/7e07c5f2-8778-4a7e-8180-fce35d9a0f11

App管理Dashboard:

https://dev.windowsphone.com/en-us/ApplicationDetails?productId=7e07c5f2-8778-4a7e-8180-fce35d9a0f11&applicationDetailsView=2

最新Issues、Featues要求:

  • 14/06/21動態磚無法更新 
  • 14/06/22 支援長方形動態磚、動態磚可以分「上班」「下班」

2013/09/15

Hackintosh kernel panic after update to OS X 10.8.5 from AppStore

My Hackintosh Hardware硬体配備:

  • GA Z77-DS3H rev 1.1
  • intel core i7 3770

Symptom 症狀

Kernel panic in AppleHDA.kext

 Resolutions 解決方法:

http://www.tonymacx86.com/articles/108809-article-os-x-10-8-5-update-5.html#post662835
http://www.macbreaker.com/2012/01/list-of-common-hackintosh-boot-flags_29.html
在chimera boot options 不要直接按Enter,要輸入 -v -x -f -s 進入verbose 、安全模式、不用cached kext (kernel module) 單人模式

$ /sbin/fsck -fy

$ /sbin/mount -uw /
用vim 或 vi或 emacs編輯 /Extra/org.chameleon.Boot.plist

$ vim /Extra/org.chameleon.Boot.plist
  1. 尋找 EthernetBuiltIn把下一行的Yes 修改成No
  2. 尋找Kernel Flags,把下一行的選項 -npci=0x3000砍掉
  3. 離開vim,exit 重開機

2013/08/19

[Cpp11] C++11 Move Semantics and RValue-Reference

為了回應 COdE fr3@K大大的Coscup2013講稿“C++: 誰說只能硬著來?”,我回家用g++49 -std=c++11實驗了,是否用std::move 搭配 RValue-Ref in constructor可否達到ZERO COPY。
#include <utility>
#include <algorithm>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;
class mystr{
public:
    int   len;
    char* buf;
    mystr()
        : len(0) , buf(NULL)
    {
        printf("trivia ctor\n");
    }
    mystr(int l)
        : len(0) , buf(NULL)
    {
        printf("length-spec ctor, l=%d\n", l);
        buf = (char*)malloc(len);
        len = l;
        memset(buf, 0, len);
    }
    mystr(const mystr& rhs){
        printf("copy ctor const& \"%s\", len=%d\n", rhs.buf,
                rhs.len);
        buf = strdup(rhs.buf);
        len = rhs.len;
    }

    ~mystr(){
        if(buf){
            printf("dtor free (\"%s\"), len=%d\n", buf, len);
            free(buf);
            buf = NULL;
            len = 0;
        }
        else{
            printf("dtor nothing to free\n");
        }
    }
    mystr(const char* rhs)
        : len(0), buf(NULL)
    {
        printf("ctor from char* \"%s\"\n", rhs);
        buf = strdup(rhs);
        len = strlen(buf);
    }

    mystr(mystr&& rhs)
        : len(0), buf(NULL)
    {
        printf("ctor RRValue; swap: buf=\"%s\" len=%d \n", rhs.buf,
                rhs.len);
        std::swap(buf, rhs.buf);
        std::swap(len, rhs.len);
    }


    mystr& operator=(const mystr& rhs){
        printf("assignment copy: \"%s\"\n", rhs.buf);
        if(buf)
            free(buf);
        buf = strdup(rhs.buf);
        len = rhs.len;
        return *this;
    }

    mystr& operator+=(const mystr& rhs){
        printf("concat \"%s\" + \"%s\", len=(%d + %d)\n", buf,
                rhs.buf, len, rhs.len);
        char* newbuf = (char*)malloc(len + rhs.len + 1);
        memcpy(newbuf, buf, len);
        memcpy(newbuf+len, rhs.buf, rhs.len);
        newbuf[len+rhs.len]=0;
        free(buf);
        buf = newbuf;
        len += rhs.len;
        return *this;
    }
};


mystr foo(mystr rhs){
    printf("etner foo\n");
    mystr ret("foo ");
    ret += rhs;
    printf("[foo] return \"%s\"\n", ret.buf);
    return ret;
}
int main(){
    mystr a("apple");
    mystr fooapple = foo( std::move(a) );
    return 0;
}

執行結果

 passing 到 foo() 函式時,若是使用std::move(),的確是ZERO COPY。看 ctor "apple"的個數,只有一開始在main()的那唯一一個,確定是zero copy。
ctor from char* "apple"
ctor RRValue; swap: buf="apple" len=5
etner foo
ctor from char* "foo "
concat "foo " + "apple", len=(4 + 5)
[foo] return "foo apple"
dtor free ("apple"), len=5
dtor free ("foo apple"), len=9
dtor nothing to free

2013/04/02

[FFMpeg Concat] Use FFMpeg to concat MP3 files of 地球村高級美語CD

#!/usr/bin/env python

# you must have ffmpeg in $PATH
import os, sys, glob

for i in range(1,14):
    flist = "|".join(glob.glob("%02d??-A.mp3" % i ))
    os.system('ffmpeg -y -i "concat:%s" -acodec copy %02d.mp3 '\
         % (flist,i) )

2013/03/27

[history of C] 為什麼Caesar古拉丁語是唸「凱撒」,但英語是唸「西撒」?

古拉丁語的C是發/k/或/g/,/k/與/g/之間只是送氣與不送氣的差異,這很好理解。但英語字中的C有時唸/s/有時唸/k/;/s/是齒齦擦音,/k/是軟顎塞音,這也差太多了吧?

西元五世紀之前,羅馬帝國版圖擴張,從原本的義大利半島擴張到大半歐陸與西亞、北非。帝國底下人民牛蛇雜處,古典拉丁語發展成了通俗拉丁語,C開始「顎化」。C碰到「軟母音」(如 Ce, Ci)時顎化成/tʃɛ/或/tʃi/。這就像中古漢語「權」是唸/kɛn/,但現化漢語是唸/tʃɛn/;中古漢語「氣」唸/ki/,現代唸/tʃi/。

西羅馬滅亡後,六世紀到九世紀間,羅曼語族(法蘭西與伊比利半島)取代通俗拉丁族,Ce、Ci變成/tsɛn/與/tsin/。大約12世紀,法國人進行拼音改革,用C去取代一些原本發ts的音的拉丁文,比如 gratia → grace。到了13世紀末,/ts/音完全「去爆擦化」(de-affricated) 變成/s/音。從此 Ce、Ci就發/sɛ/與/si/的音。

再來,雙母音ae在古典拉丁文是唸/ai/,但雙母音在中古英語末年遭遇「母音大推移」,發音會把前母音省略掉,如oe→e,ae→e。Caesar此字在英文中雖仍保持古拉丁語的模樣,但a不發音了,變Cesar,然後C從/tʃ/變/ts/再變/s/,所以現代英語是發/ˈsizɚ/。