Skip to content

Instantly share code, notes, and snippets.

@e9t
Last active June 9, 2020 06:09
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save e9t/ba9edd99793a5c91eaab to your computer and use it in GitHub Desktop.
Save e9t/ba9edd99793a5c91eaab to your computer and use it in GitHub Desktop.
식신로드 만점 식단 20선
#! /usr/bin/python3
# -*- coding: utf-8 -*-
from lxml import html
import requests
APIKEY = '' # 이 곳에 네이버 API 키를 입력 (http://developer.naver.com/wiki/pages/OpenAPI)
MAPAPI = 'http://openapi.map.naver.com/api/geocode.php?key=%s&encoding=utf-8&coord=LatLng&query=%s'
def get_latlon(query):
root = html.parse(MAPAPI % (APIKEY, query))
lon, lat = root.xpath('//point/x/text()')[0], root.xpath('//point/y/text()')[0]
return (lat, lon)
def prep(item):
n, name = item[0].split(' ', 1)
lat, lon = get_latlon(item[3])
return {
'num': n, 'name': name,
'lat': lat, 'lon': lon,
'description': item[1],
'phone': item[2],
'addr': item[3]
}
# get data from article
r = requests.get('http://m.wikitree.co.kr/main/news_view.php?id=217101')
root = html.document_fromstring(r.text)
string = '\n'.join(root.xpath('//div[@id="ct_size"]/div//text()'))
items = []
for i in range(1, 21):
tmp = string.split('%s.' % i, 1)
string = tmp[1]
items.append([j.strip() for j in tmp[0].split('\n') if j and j!='\xa0'])
data = [prep(i[:4]) for i in items[1:]]
# save data to file
with open('places.csv', 'w') as f:
f.write('name,lat,lon\n')
for d in data:
f.write('%(name)s,%(lat)s,%(lon)s\n' % d)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
svg circle {
fill: orange;
opacity: .5;
stroke: white;
}
svg circle:hover {
fill: red;
stroke: #333;
}
svg text {
pointer-events: none;
}
svg .municipality {
fill: #efefef;
stroke: #fff;
}
svg .municipality-label {
fill: #bbb;
font-size: 12px;
font-weight: 300;
text-anchor: middle;
}
svg #map text {
color: #333;
font-size: 10px;
text-anchor: middle;
}
svg #places text {
color: #777;
font: 10px sans-serif;
text-anchor: start;
}
#title {
font-family: sans-serif;
}
#title p {
font-size: 10pt;
}
</style>
</head>
<body>
<div id="chart"></div>
<div id="title">
<h2>식신로드 서울지역 만점식단 20선</h2>
<p>식신로드에서 만점을 받은 음식점을 D3.js, TopoJSON을 이용해 지도를 그렸습니다.
지도 만드는 법은 <a href="http://www.lucypark.kr/blog/2015/06/24/seoul-matzip-mapping/">D3를 이용한 서울시내 맛집 시각화 (Feat. 식신로드)</a>를 참고해주세요.
<p>
<a href="http://www.wikitree.co.kr/main/news_view.php?id=217101">Data</a> by Wikitree</a>
and <a href="https://gist.github.com/e9t/ba9edd99793a5c91eaab">code</a>
by <a href="http://lucypark.kr">Lucy Park</a>.
<br>
<a href="http://opensource.org/licenses/Apache-2.0">Licensed with Apache 2.0</a>
</p>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 800,
height = 600;
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height);
var map = svg.append("g").attr("id", "map"),
places = svg.append("g").attr("id", "places");
var projection = d3.geo.mercator()
.center([126.9895, 37.5651])
.scale(100000)
.translate([width/2, height/2]);
var path = d3.geo.path().projection(projection);
d3.json("seoul_municipalities_topo_simple.json", function(error, data) {
var features = topojson.feature(data, data.objects.seoul_municipalities_geo).features;
map.selectAll('path')
.data(features)
.enter().append('path')
.attr('class', function(d) { console.log(); return 'municipality c' + d.properties.code })
.attr('d', path);
map.selectAll('text')
.data(features)
.enter().append("text")
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("dy", ".35em")
.attr("class", "municipality-label")
.text(function(d) { return d.properties.name; })
});
d3.csv("places.csv", function(data) {
places.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("cx", function(d) { return projection([d.lon, d.lat])[0]; })
.attr("cy", function(d) { return projection([d.lon, d.lat])[1]; })
.attr("r", 10);
places.selectAll("text")
.data(data)
.enter().append("text")
.attr("x", function(d) { return projection([d.lon, d.lat])[0]; })
.attr("y", function(d) { return projection([d.lon, d.lat])[1] + 8; })
.text(function(d) { return d.name });
});
</script>
</body>
</html>
name lat lon
다성일식 37.5569016 126.9329799
봉산집 37.5344248 126.9750082
창고43 37.5189582 126.9307458
돕감자탕 37.5414873 127.0692836
대보명가 37.6456867 127.0071573
해뜨는집 37.5900691 127.0084044
아이 해브어 드림 37.4986175 127.0278876
아현동 간장게장 37.5546000 126.9561000
왕소금구이 37.5204088 127.0361107
라틀리에 모니크 37.5261816 127.0448766
비스트로 딩고 37.5210777 127.0198099
줄리에뜨 37.4947204 127.0009384
충주집 37.5862178 127.0345490
영화루 37.5801384 126.9690401
일품헌 37.4845029 127.0391935
립스테이크 37.5955682 126.9640695
오가와 37.5720260 126.9743351
까사디노아 37.5620845 126.9235561
충무로 주꾸미 불고기 37.5617693 126.9921966
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@Charlsoun
Copy link

안녕하세요.
올려주신 코드보고 정말 많은 공부 되었습니다.
특히 '스시야 기행' 코드를 보고 서울시에서 세종시로 바꾸어 적용하는데 큰 도움이 되었습니다.
하지만 진행하다가 한가지 문제에 도달했는데요 ㅠ Github나 bl.ocks를 참고해도 제 내공이 부족하여 답을 얻어내지 못했습니다. 혹시 루시님이 시간되실때 도와주신다면 정말 감사하겠습니다.
우선 제가 구축한 페이지는 아래와 같습니다.
http://cshin.me/sejongmat_b...
여기서 Force Layout된 "text"에 URL을 넣어 연결하고 싶은데... 마음같이 안되네요 ㅠ
'Circle'이 겹치는 부분의 경우 링크를 타고 가는게 어려우니까요... ㅠ

혹시라도 도와주시거나 조금의 힌트라도 주신다면 정말 큰 도움이 될 것 같습니다.

감사합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment