웹 API
웹 API는 웹 애플리케이션 개발에서 다른 서비스에 요청을 보내고 응답을 받기 위해 정의된 것이다.
예를 들어 블로그 API를 이용하면 블로그에 접속하지 않고도 다른 방법으로 글을 올릴 수 있다.
그 외에 우체국의 우편번호 API, 구글과 네이버의 지도 API등 유용한 API들이 많으므로, 요즘은 홈페이지 구축이나 추가개편 시 따로 추가로 개발하지 않고 이런 오픈 API를 가져와 사용하는 추세다.
Google Map API
#1 환경 구축하기
구글 map api 제공 사이트:https://cloud.google.com/maps-platform
1. 시작하기
2. 원하는 제품 선택
3. 프로젝트 이름 설정
4.결제 방법 설정 (실제로 결제 안됨으로 걱정 안해도 됨)
5. 사용할 수 있는 인증키 발급
6. 명령 프롬프트에서 google maps 다운
(1)pip install googlemaps
+ pip:간단하게 말하면 라이브러리들의 설치를 아주아주 편하고 쉽게 도와주는 프로그램.
(2)pip install folium
+folium위치정보를 시각화하기 위한 라이브러리다
#2 파이썬으로 활용하기
원하는 장소의 정보 불러오기
import googlemaps
gmaps =googlemaps.Client(key=gmaps_key(부여받은 개인키))
geo=gmaps.geocode('대한민국 서울특별시 강남구 대치2동 514')
print(geo)
결과값
결과값을 보면 정리가 안된 json 파일형태로 출력된다.
아래는 보기편하게 정리된 json 형태로 정리한 것이다.
[{
'access_points': [],
'address_components': [{
'long_name': '514',
'short_name': '514',
'types': ['premise']
}, {
'long_name': '대치2동',
'short_name': '대치2동',
'types': ['political', 'sublocality', 'sublocality_level_2']
}, {
'long_name': '강남구',
'short_name': '강남구',
'types': ['political', 'sublocality', 'sublocality_level_1']
}, {
'long_name': '서울특별시',
'short_name': '서울특별시',
'types': ['administrative_area_level_1', 'political']
}, {
'long_name': '대한민국',
'short_name': 'KR',
'types': ['country', 'political']
}, {
'long_name': '135-282',
'short_name': '135-282',
'types': ['postal_code']
}],
'formatted_address': '대한민국 서울특별시 강남구 대치2동 514',
'geometry': {
'location': {
'lat': 37.495846,
'lng': 127.0722393
},
'location_type': 'ROOFTOP',
'viewport': {
'northeast': {
'lat': 37.4971949802915,
'lng': 127.0735882802915
},
'southwest': {
'lat': 37.4944970197085,
'lng': 127.0708903197085
}
}
},
'place_id': 'ChIJpS4nCDCkfDURrKqALLHBeXo',
'plus_code': {
'compound_code': 'F3WC+8V 대한민국 서울특별시',
'global_code': '8Q99F3WC+8V'
},
'types': ['street_address']
}]
주소를 분리해서 출력하기
#주소 분리
from urllib.parse import quote
from urllib.request import Request, urlopen
import ssl
import json
kor_url = quote('대한민국 서울특별시 강남구 대치2동 514')
url = 'https://maps.googleapis.com/maps/api/geocode/json?address='+ kor_url +
'&key=''부여받은 개인키''&language=ko'
req = Request(url, headers={ 'X-Mashape-Key': 'key(부여받은 개인키)' })
ssltext = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
company_addr_json = urlopen(req, context=ssltext).read().decode('utf8')
addr = json.loads(company_addr_json)
addr_detail = addr['results'][0]
#전체 주소
full_addr = addr_detail['formatted_address']
#시도 주소
city_addr1 = addr_detail['address_components'][4]['long_name']
#구 주소
city_addr = addr_detail['address_components'][3]['long_name']
#동,읍 주소
go_addr = addr_detail['address_components'][2]['long_name']
#대로 주소
dong_addr = addr_detail['address_components'][1]['long_name']
#번지 주소
bunji_addr = addr_detail['address_components'][0]['long_name']
print(addr_detail)
print(full_addr)
print(city_addr1)
print(city_addr)
print(go_addr)
print(dong_addr)
print(bunji_addr)
json의 배열인덱스들을 지정해줘서 원하는 값들을 뽑아낸다
좌표로 지도 저장
#좌표로 지도 저장
import folium
map_osm = folium.Map(location=[37.566345, 126.977893],zoom_start=17)
map_osm.save('C:\제혁\지도 사진들/map2.html')
좌표에 마크 지정
#좌표에 마크 지정
import folium
map_osm = folium.Map(location=[37.566345, 126.977893],zoom_start=17)
folium.Marker([37.566345, 126.977893], popup='서울특별시청').add_to(map_osm)
map_osm.save('C:\제혁\지도 사진들/map1.html')
좌표 사이 거리 구하기
#좌표 사이 거리 구하기
import numbers
import math
class GeoUtil:
"""
Geographical Utils
"""
@staticmethod
def degree2radius(degree):
return degree * (math.pi/180)
@staticmethod
def get_harversion_distance(x1, y1, x2, y2, round_decimal_digits=5):
"""
경위도 (x1,y1)과 (x2,y2) 점의 거리를 반환
Harversion Formula 이용하여 2개의 경위도간 거래를 구함(단위:Km)
"""
if x1 is None or y1 is None or x2 is None or y2 is None:
return None
assert isinstance(x1, numbers.Number) and -180 <= x1 and x1 <= 180
assert isinstance(y1, numbers.Number) and -90 <= y1 and y1 <= 90
assert isinstance(x2, numbers.Number) and -180 <= x2 and x2 <= 180
assert isinstance(y2, numbers.Number) and -90 <= y2 and y2 <= 90
R = 6371 # 지구의 반경(단위: km)
dLon = GeoUtil.degree2radius(x2-x1)
dLat = GeoUtil.degree2radius(y2-y1)
a = math.sin(dLat/2) * math.sin(dLat/2) \
+ (math.cos(GeoUtil.degree2radius(y1)) \
*math.cos(GeoUtil.degree2radius(y2)) \
*math.sin(dLon/2) * math.sin(dLon/2))
b = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return round(R * b, round_decimal_digits)
@staticmethod
def get_euclidean_distance(x1, y1, x2, y2, round_decimal_digits=5):
"""
유클리안 Formula 이용하여 (x1,y1)과 (x2,y2) 점의 거리를 반환
"""
if x1 is None or y1 is None or x2 is None or y2 is None:
return None
assert isinstance(x1, numbers.Number) and -180 <= x1 and x1 <= 180
assert isinstance(y1, numbers.Number) and -90 <= y1 and y1 <= 90
assert isinstance(x2, numbers.Number) and -180 <= x2 and x2 <= 180
assert isinstance(y2, numbers.Number) and -90 <= y2 and y2 <= 90
dLon = abs(x2-x1) # 경도 차이
if dLon >= 180: # 반대편으로 갈 수 있는 경우
dLon -= 360 # 반대편 각을 구한다
dLat = y2-y1 # 위도 차이
return round(math.sqrt(pow(dLon,2)+pow(dLat,2)),round_decimal_digits)
# 서울시청 126.97843, 37.56668
# 강남역 127.02758, 37.49794
print(GeoUtil.get_euclidean_distance(126.97843, 37.56668, 127.02758, 37.49794))
결과값:0.0845
받아오는 값의 주소 원리
주소의 기본 틀
https://maps.googleapis.com/maps/api/directions/json?origin&destination&mode&departure_time&key
- origin = 위도, 경도
설명 : 출발지
예시 : origin=41.43206,-81.38992
주의할점 : 위도와 경도 사이에 공백 없어야함 문자열 형식으로 묶지말고 숫자로 바로 쓸 것
- destination = 위도, 경도
설명 : 도착지
예시 : destination=41.43206,-81.38992
주의할 점 : 위도와 경도 사이에 공백 없어야함, 문자열 형식으로 묶지말고 숫자로 바로 쓸 것
- mode = driving, walking, bicycling, transit
설명 : 길찾기 모드를 선택한다. 기본값은 driving 이며, 각각 도보, 자전거, 대중교통을 나타낸다.
- departure_time = 초단위정수
설명 : 출발 시간을 설정 할 수 있다.
예시 : departure_time=1343641500 일 경우 2012 년 7 월 30 일 오전 9:45에 출발 하도록 설정한 값인데, 이는 UTC 1970 년 1월 1일 0시 0분 0초 부터 경과한 초를 정수로 반환한 값을 사용한다. 만약 지금 시간으로 설정하고 싶을경우 departure_time=now로 입력하면 된다.
적용된 주소
https://maps.googleapis.com/maps/api/directions/json?origin=37.5728359,126.9746922&destination=37.5129907,127.1005382&mode=transit&departure_time=now&key=API Key
중요!!! 걸리는 시간 초로 나타내기
설정한 주소값들을 적용
#중요!!! 걸리는 시간 초로 나타내기
# coding: utf-8
import time
import json
import os
import ssl
import urllib.request
if (__name__ == "__main__") :
origin = "37.5728359,126.9746922"
destination = "37.5129907,127.1005382"
mode = "transit"
departure_time = "now"
key = 'key(부여받은 개인키)'
url = "https://maps.googleapis.com/maps/api/directions/json?origin="+ origin \
+ "&destination=" + destination \
+ "&mode=" + mode \
+ "&departure_time=" + departure_time\
+ "&language=ko" \
+ "&key=" + key
request = urllib.request.Request(url)
context = ssl._create_unverified_context()
response = urllib.request.urlopen(request, context=context)
responseText = response.read().decode('utf-8')
responseJson = json.loads(responseText)
with open("./Agent_Transit_Directions.json","w") as rltStream :
json.dump(responseJson,rltStream)
if ( __name__ == "__main__" ) :
wholeDict = None
with open("./Agent_Transit_Directions.json","r") as transitJson :
wholeDict = dict(json.load(transitJson))
path = wholeDict["routes"][0]["legs"][0]
duration_sec = path["duration"]["value"]
start_geo = path["start_location"]
end_geo = path["end_location"]
print(duration_sec) #전체 걸리는 시간을 초로 나타낸 것
print(start_geo) #출발지 위도,경도
print(end_geo) #도착지 위도,경도
결과값
//걸리는 초
3394
//출발하는 위도와 경도
{'lat': 37.5728359, 'lng': 126.9746922}
//도착하는 위도와 경도
{'lat': 37.5129907, 'lng': 127.1005382}
위도 경도 추출
##위도 경도 추출
import requests
# 검색할 주소
location = '강남 할리스'
# 요청 주소(구글맵)
# Local(테스트) 환경 - https 요청이 필요없고, API Key가 따로 필요하지 않지만 횟수에 제약이 있습니다.
URL = 'http://maps.googleapis.com/maps/api/geocode/json?sensor=false&language=ko&address={}' \
.format(location)
# Production(실제 서비스) 환경 - https 요청이 필수이고, API Key 발급(사용설정) 및 과금 설정이 반드시 필요합니다.
URL = 'https://maps.googleapis.com/maps/api/geocode/json?key=key(부여받은 개인키)' \
'&sensor=false&language=ko&address={}'.format(location)
# URL로 보낸 Requst의 Response를 response 변수에 할당
response = requests.get(URL)
# JSON 파싱
data = response.json()
# lat, lon 추출
lat = data['results'][0]['geometry']['location']['lat']
lng = data['results'][0]['geometry']['location']['lng']
# print() 함수 대신 pprint.pprint() 함수를 사용하는 이유는 좀 더 보기 쉽게 출력하기 위함입니다.
print(lat)
print(lng)
//위도
37.49873340000001
//경도
127.0278077
'python 프로젝트(google map api)' 카테고리의 다른 글
프로젝트(카페 선주문 프로그램) (0) | 2020.05.27 |
---|