2015年11月19日 星期四

[R] 計算經緯度距離

可利用Imap library計算兩經緯度之間距離,R Script如下:
library(Imap)

gdist(121.24056,25.10048,121.2945078,25.1003632,units = "km")
unit可切換距離單位

結果如下
> gdist(121.24056,25.10048,121.2945078,25.1003632,units = "km")
[1] 5.441616

也可利用下列function計算
# Calculate distance in kilometers between two points
earth.dist = function (long1, lat1, long2, lat2){
rad = pi/180
a1 = lat1 * rad
a2 = long1 * rad
b1 = lat2 * rad
b2 = long2 * rad
dlon = b2 - a2
dlat = b1 - a1
a = (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
R = 6378.145
d = R * c
return(d)
}

> earth.dist(121.24056,25.10048,121.2945078,25.1003632)
[1] 5.438344

[R] Google map POI資料撈取

ref: https://developers.google.com/places/web-service/details
擷取Google map POI須先至Google developers console開啟Google Places API Web Service,點選憑證產生API金鑰(須依狀況選擇瀏覽器金鑰or伺服器金鑰)

























輸入下列網址即可獲得XML or JSON(此範例為XML)
https://maps.googleapis.com/maps/api/place/nearbysearch/[data type]?location=[latitude,longitude]&radius=[radius]&type=[POI type]&key=[API key]

POI type如下:
accounting casino gas_station meal_takeaway rv_park
airport cemetery general_contractor mosque school
amusement_park church grocery_or_supermarket movie_rental shoe_store
aquarium city_hall gym movie_theater shopping_mall
art_gallery clothing_store hair_care
moving_company
spa
atm convenience_store hardware_store museum stadium
bakery courthouse health night_club storage
bank dentist hindu_temple painter store
bar department_store home_goods_store park subway_station
beauty_salon doctor hospital parking synagogue
bicycle_store electrician insurance_agency pet_store taxi_stand
book_store electronics_store jewelry_store pharmacy train_station
bowling_alley
embassy
laundry physiotherapist travel_agency
bus_station establishment lawyer place_of_worship university
cafe finance library plumber veterinary_care
campground fire_station liquor_store police zoo
car_dealer florist local_government_office post_office  
car_rental food locksmith real_estate_agency  
car_repair funeral_home lodging restaurant  
car_wash furniture_store meal_delivery roofing_contractor  

ex:
https://maps.googleapis.com/maps/api/place/nearbysearch/xml?location=24.68292,121.77701&radius=500&key=AIzaSyB7TlT-xxxxxxxxxxxxx























Note1: 每頁XML只會顯示20筆資料,XML中有next_page_token代表有下頁資料,因此須繼續抓取,URL產生規則如下:
https://maps.googleapis.com/maps/api/place/nearbysearch/xml?pagetoken=[next_page_token]&key=[apiKey]

Note2: Google非常賤...爬太快會被擋...所以增加Sys.sleep指令random時間抓取

#輸入 latitude = 緯度, longitude = 經度, radius = 距離範圍(單位為公尺), type = 類型, apiKey = POI金鑰. ex:POI(25.08638,121.5241788,500,"food","AIzaSyAPZgJ024rQVxenR9raBvGz5DQVGJ84_I0")
POI = function(latitude, longitude, radius, type, apiKey) {
#url root
root = "https://maps.googleapis.com/maps/api/place/nearbysearch/"
#POI API型態(XML or JSON)
return.call = "xml"
#產生URL List
url_gen = array()
url_gen[1] = paste(root, return.call, "?location=", latitude, ",", longitude, "&radius=", radius, "&type=", type, "&key=", apiKey, sep = "")
#產生物件名稱清單(html_code_1, html_code_2, ....)
object_name_list = array()
object_name_list[1] = paste("html_code", 1, sep = "_")
#擷取網頁原始碼
assign(object_name_list[1], getURL(url_gen[1], useragent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", .opts = list(ssl.verifypeer = FALSE)))
assign(object_name_list[1], xmlParse(get(object_name_list[1])))
#若status不為OK則跳開
if (xpathSApply(get(object_name_list[1]),"//status",xmlValue) != "OK"){
print(paste("Status:", xpathSApply(get(object_name_list[1]),"//status",xmlValue), sep = " "))
break
}
name = xpathSApply(get(object_name_list[1]),"//result//name",xmlValue)
addr = xpathSApply(get(object_name_list[1]),"//result//vicinity",xmlValue)
lat = xpathSApply(get(object_name_list[1]),"//result//geometry//location//lat",xmlValue)
lng = xpathSApply(get(object_name_list[1]),"//result//geometry//location//lng",xmlValue)
#取token值
next_page_token = xpathSApply(get(object_name_list[1]),"//next_page_token",xmlValue)
#若有next_page_token, 繼續執行迴圈
if (is.list(xpathSApply(get(object_name_list[1]),"//next_page_token",xmlValue)) == TRUE) break
i = 2
repeat{
#透過next_page_token產生URL
url_gen[i] = paste(root, return.call, "?pagetoken=", next_page_token, "&key=", apiKey, sep = "")
#新增物件名稱
object_name_list[i] = paste("html_code", i, sep = "_")
#因Google有防止機器人接取, 需占停時間執行網頁原始碼擷取
Sys.sleep(sample(10:20, 1))
#擷取網頁原始碼
assign(object_name_list[i], getURL(url_gen[i], useragent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36", .opts = list(ssl.verifypeer = FALSE)))
assign(object_name_list[i], xmlParse(get(object_name_list[i])))
#若status不為OK則跳開
if (xpathSApply(get(object_name_list[i]),"//status",xmlValue) != "OK"){
print(paste("Status:", xpathSApply(get(object_name_list[i]),"//status",xmlValue), sep = " "))
break
}
name = as.vector(rbind(name, xpathSApply(get(object_name_list[i]),"//result//name",xmlValue)))
addr = as.vector(rbind(addr, xpathSApply(get(object_name_list[i]),"//result//vicinity",xmlValue)))
lat = as.vector(rbind(lat, xpathSApply(get(object_name_list[i]),"//result//geometry//location//lat",xmlValue)))
lng = as.vector(rbind(lng, xpathSApply(get(object_name_list[i]),"//result//geometry//location//lng",xmlValue)))
#取token值
next_page_token = xpathSApply(get(object_name_list[i]),"//next_page_token",xmlValue)
#若有next_page_token, 繼續執行迴圈
if (is.list(xpathSApply(get(object_name_list[i]),"//next_page_token",xmlValue)) == TRUE) break
i = i + 1
}
#return最後結果
return(cbind(name, addr, lat, lng))
}

name addr lat lng
Huge Burger No. 14, Xiaodong Street, Shilin District 25.0888706 121.5261431
帝二泰皇卷 No. 4, Daxi Road, Shilin District 25.0896858 121.5241363
松竹梅壽司 No. 1號, Lane 17, Hualing Street, Shilin District 25.082956 121.5193239
Family Mart No. 2, Hefeng Street, Shilin District 25.0828011 121.5194107
便所 No. 184, Wenlin Road, Shilin District 25.0896728 121.5270706
咖啡物語 號, No. 28, Dabei Road, Shilin District 25.089737 121.52713
士林生炒羊肉 No. 21之3號, Dadong Road, Shilin District 25.0887613 121.5250143
阿亮麵線 No. 84號, Danan Road, Shilin District 25.0894903 121.5246627
草原風蒙古火鍋 No. 35, Hougang Street, Shilin District 25.0836565 121.5229606
阿姨鹽水雞 No. 15, Jihe Road, Shilin District 25.0880218 121.5237378
阿輝麵線 台北市士林區大南路(士林夜市,慈誠宮前) 25.0893912 121.5249056
大統一牛排 No. 89之17號, Danan Road, Shilin District 25.0881567 121.5239742
笨蘆 No. 189, Section 4, Chengde Road, Shilin District 25.0880846 121.5223565
Cool N2分子虎分子雪糕專賣店 士林店 No. 107, Danan Road, Shilin District 25.0895579 121.5239008
肯德基KFC-台北士林餐廳 No. 88, Wenlin Road, Shilin District 25.08729 121.525953
Hilife No. 7號, Dadong Road, Shilin District 25.0866371 121.5253067
品麻辣臭豆腐 No. 113, Wenlin Road, Shilin District 25.0882133 121.5261244
越南祥記美食 No. 26, Xiaodong Street, Shilin District 25.0892004 121.5262561
幸也蛋包飯 台北市士林區大北路12號 25.089764 121.5266381
咭家 No. 36, Xiaodong Street, Shilin District 25.089407 121.5263265
2派克脆皮雞排 士林店 No. 181, Jihe Road, Shilin District 25.0896957 121.5228589
好了啦-文林小北店 No. 1, Xiaobei Street, Shilin District 25.0902013 121.5269157
Ba Fang Yun Ji Dumpling No. 31號, Hualing Street, Shilin District 25.083599 121.519345
勝力食堂 No. 35, Daxi Road, Shilin District 25.0906726 121.524388
咖啡弄(劍潭店) No. 132, Wenlin Road, Shilin District 25.088581 121.526587
台南海鮮 No. 130, Jihe Road, Shilin District 25.0891115 121.5229285
士林伯豆花 No. 94號, Danan Road, Shilin District 25.0895679 121.524301
OK Mart No. 78號, Dadong Road, Shilin District 25.090465 121.5258699
Double Content No. 50, Danan Road, Shilin District 25.0893677 121.5249322
學姐冰店 Shilin District 25.0894329 121.5262616
阿宗面線 台北市士林區文林路101巷24號1樓 25.0878452 121.5255832
咕咕雞脆皮雞排 No. 47號, Danan Road, Shilin District 25.0892459 121.5249629
DSH No. 99, Wenlin Road, Shilin District 25.087939 121.5260559
寒天脆皮雞蛋燒 台北市士林區大南路(面對士林廟口左側) 25.0895657 121.5243915
海友十全排骨 No. 49號, Dadong Road, Shilin District 25.0896619 121.5252989
UNCLEVINCE墨西哥雞肉捲 台北市士林區大南路84號 25.089522 121.524684
鍾家原上海生煎包 No. 38, Xiaodong Street, Shilin District 25.0894417 121.5263384
南港老老面碳烤 台北市士林區基河路181號 25.0896829 121.5229633
吳記螃蟹羹 台北市士林區文林路101巷26號 25.087824 121.5255496
麻辣妹子精緻99涮涮鍋 No. 61, Dabei Road, Shilin District 25.0900559 121.5252918
富樂台式涮涮鍋 No. 75-1, Section 4, Chengde Road, Shilin District 25.0820676 121.5233911
帝二泰皇卷 No. 4, Daxi Road, Shilin District 25.0896858 121.5241363
河粉煎 Lane 101, Wenlin Road, Shilin District 25.0877196 121.5256212
Family Mart No. 2, Hefeng Street, Shilin District 25.0828011 121.5194107
家鄉涼麵 No. 46, Danan Road, Shilin District 25.0893379 121.5250396
咖啡物語 號, No. 28, Dabei Road, Shilin District 25.089737 121.52713
沙茶滷味 台北市士林區大東路11-3號旁 25.087015 121.5252631
阿亮麵線 No. 84號, Danan Road, Shilin District 25.0894903 121.5246627
蜜酥雞排 台北市士林區文林路115號(士林夜市陽明戲院旁) 25.087984 121.526105
阿姨鹽水雞 No. 15, Jihe Road, Shilin District 25.0880218 121.5237378
郭家蔥油餅 口, Lane 101, Wenlin Road, Shilin District 25.08809 121.5261875
大統一牛排 No. 89之17號, Danan Road, Shilin District 25.0881567 121.5239742
錢都日式涮涮鍋-承德直營店 No. 79, Section 4, Chengde Road, Shilin District 25.082275 121.523368
Cool N2分子虎分子雪糕專賣店 士林店 No. 107, Danan Road, Shilin District 25.0895579 121.5239008
炭烤 台北市士林區基河路181號 25.0896815 121.5229954
Hilife No. 7號, Dadong Road, Shilin District 25.0866371 121.5253067
咕咕雞小火鍋 No. 47, Danan Road, Shilin District 25.0892693 121.5249713
越南祥記美食 No. 26, Xiaodong Street, Shilin District 25.0892004 121.5262561
日上鐵板燒 No. 101, Jihe Road, Shilin District 25.087867 121.5241048
咭家 No. 36, Xiaodong Street, Shilin District 25.089407 121.5263265
食來運轉 No. 31, Xiaodong Street, Shilin District 25.089343 121.5262322
好了啦-文林小北店 No. 1, Xiaobei Street, Shilin District 25.0902013 121.5269157
泰便宜南洋小吃 No. 130號, Danan Road, Shilin District 25.0898554 121.5232556
勝力食堂 No. 35, Daxi Road, Shilin District 25.0906726 121.524388
食尚曼谷 bistro & lounge No. 54, Dadong Road, Shilin District 25.0897525 121.5254716
台南海鮮 No. 130, Jihe Road, Shilin District 25.0891115 121.5229285
喇度的廚房 Shilin District 25.0882157 121.5262236
OK Mart No. 78號, Dadong Road, Shilin District 25.090465 121.5258699
家鄉碳烤香雞排 台北市士林區基河路(都會叢林門口) 25.0861476 121.5249843
學姐冰店 Shilin District 25.0894329 121.5262616
Ikari Coffee 台北市, 台北市士林區士商路1號, 士林區 25.0890077 121.5216101
咕咕雞脆皮雞排 No. 47號, Danan Road, Shilin District 25.0892459 121.5249629
王叔叔雞蛋糕 台北市士林區基河路15號(麥當勞前) 25.0868212 121.5246917
寒天脆皮雞蛋燒 台北市士林區大南路(面對士林廟口左側) 25.0895657 121.5243915
福串炸 No. 5, Daxi Road, Shilin District 25.0897259 121.5240765
UNCLEVINCE墨西哥雞肉捲 台北市士林區大南路84號 25.089522 121.524684
Brundi Coffee Shop No. 102, Wenlin Road, Shilin District 25.0878644 121.5263133
南港老老面碳烤 台北市士林區基河路181號 25.0896829 121.5229633
好朋友涼麵 No. 31, Danan Road, Shilin District 25.0891172 121.5255382
麻辣妹子精緻99涮涮鍋 No. 61, Dabei Road, Shilin District 25.0900559 121.5252918