From e32633e9a6b835b890773f5f3ee3df10f684ef28 Mon Sep 17 00:00:00 2001 From: Haewon Kam Date: Wed, 9 Sep 2026 13:51:28 +0900 Subject: [PATCH] =?UTF-8?q?feat(supporters):=20/en/stay=20=EB=A5=BC=20?= =?UTF-8?q?=EC=B0=B8=EA=B3=A0=20=EC=82=AC=EC=9D=B4=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EB=8B=A4=EC=8B=9C=20=EC=A7=80?= =?UTF-8?q?=EC=9D=8C=20=E2=80=94=20=EC=84=A4=EB=AA=85=EB=AC=B8=C2=B7?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=EC=8B=9C=EA=B0=84=C2=B7=EA=B3=84=EC=A0=88?= =?UTF-8?q?=EC=B6=95=EC=A0=9C=C2=B7=EB=8F=99=EC=84=A0=C2=B7=EB=82=A0?= =?UTF-8?q?=EC=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit haewon 이 준 참고 사이트(스테이,머뭄)의 연동 범위에 맞춰 다시 만들었다. 앞서 만든 것은 거리순 표였고, 실제로 필요한 것은 설명문과 이동 시간이 붙은 카드, 계절로 묶은 축제, 시간표가 있는 동선이었다. 수집 (scripts/fetch_medical_tourism.py) - detailCommon2 의 overview 를 가져온다. locationBasedList2 는 설명문을 주지 않아 카드에 이름과 주소만 남았다. 123/125 건 확보. - 이동 시간을 낸다. 참고 사이트 표기를 역산해 도보는 max(1, round(m/80)), 차는 직선거리 km x 1.2 로 맞췄다(135m→2분, 566m→7분, 25km→30분). 2km 까지 도보로 보고, 짧은 거리의 차 시간은 주차·신호 때문에 의미가 없어 최소 5분으로 둔다. - 축제를 계절로 분류하고, 도보 시간 구간별 건수를 누적으로 집계한다. 사진 (125/125, 전부 실제로 열리는 것 확인) 목록 API 의 firstimage 만 쓰면 38건이 비었다. 폴백을 넷으로 걸었다. 1) detailImage2 — 이미지 전용 오퍼레이션. 15건 회수(도산공원 7장이 여기 있었다) 2) 국문 서비스 KorService2 — 영문 항목에 없어도 국문 항목에 있다. 10건 3) 업체 공식 홈페이지 og:image — 2건 4) Naver 이미지 검색 API — 11건 og:image 는 실제로 열어 보고 쓴다. 이미지가 아니거나 인스타 CDN 처럼 핫링크를 403 으로 막으면 화면에서 빈 칸이 되기 때문이다. imageSource 를 항목마다 남겼다. naver 출처는 제3자 저작물이므로 내부 시연 범위이며, 공개 배포 전에는 걷어내거나 라이선스 있는 사진으로 교체해야 한다(haewon 판단). 화면 (supporters/src/pages/en/stay.astro) - Around the clinic: 도보 시간 누적 필터, 범주별 카드, 사진 위 이동시간 배지, 설명문, 공식 홈페이지가 있으면 링크하고 없으면 검색으로 보낸다. - Festivals: 계절 탭. - Shaping your days: 좌표로 그린 인라인 SVG 지도와 시간표. 외부 지도 라이브러리를 부르지 않는다. 시각은 가정이며 화면에 그렇게 적었다. - 오늘 날씨: Open-Meteo, 키 불필요. 빌드가 아니라 브라우저에서 받는다. 정적 빌드에 넣으면 배포 시각의 날씨가 굳는다. 못 받으면 블록을 통째로 숨긴다. 문구는 이 페이지의 목록에만 연결한다. 무엇을 해도 되는지는 의학 판단이라 말하지 않는다. - 섹션 점프 바(글래스, 스티키) + IntersectionObserver 스크롤 스파이. 고친 것 - 항목마다 붙던 KO 태그를 헤더 언어 스위치 하나로 바꿨다. 짝이 있는 페이지는 서로 잇고 없으면 그 언어의 입구로 보낸다. 영문 페이지가 늘면 PAIRS 표에 줄만 추가한다. - .chip 클래스가 이미 있어 홈·뉴스룸·영상 페이지를 덮어쓰고 있었다. 새 스타일을 .stay 아래로 모두 가뒀다. - factSheet 에 영문 주소(fullEn)와 우편번호를 넣었다. 근거는 뷰성형외과 자신의 한국관광공사 등재 항목(contentid 3364779)이며 fullEnSource 에 적었다. 템플릿은 같은 코드에 빈 데이터 스캐폴드를 둔다. 뷰성형외과 데이터가 새 병원 빌드로 새면 안 된다. Co-Authored-By: Claude Opus 5 (1M context) --- scripts/fetch_medical_tourism.py | 218 ++- supporters/src/data/factSheet.json | 3 + supporters/src/data/medicalTourism.json | 1181 ++++++++++++++++- supporters/src/layouts/Base.astro | 23 +- supporters/src/pages/en/stay.astro | 448 +++++-- supporters/src/styles/global.css | 186 +++ .../supporters-astro/src/data/factSheet.json | 2 +- .../src/data/medicalTourism.json | 9 +- .../supporters-astro/src/layouts/Base.astro | 23 +- .../supporters-astro/src/pages/en/stay.astro | 448 +++++-- .../supporters-astro/src/styles/global.css | 186 +++ 11 files changed, 2495 insertions(+), 232 deletions(-) diff --git a/scripts/fetch_medical_tourism.py b/scripts/fetch_medical_tourism.py index 4b0f567..86cc364 100644 --- a/scripts/fetch_medical_tourism.py +++ b/scripts/fetch_medical_tourism.py @@ -20,7 +20,7 @@ INFINITH 제품 화면(/discovery)이 아니라 병원 서포터즈 사이트에 python3 scripts/fetch_medical_tourism.py python3 scripts/fetch_medical_tourism.py --out supporters/src/data/medicalTourism.json """ -import argparse, io, json, math, os, ssl, sys, time, urllib.parse, urllib.request +import argparse, io, json, math, os, re, ssl, sys, time, urllib.parse, urllib.request ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -33,6 +33,9 @@ CAT_WELLNESS = ("A02020300", "A02020400") # Hot Springs & Spa, Jjimjilbang # 다국어 ContentTypeId. 국문과 코드가 다르다. # 반경은 목적에 따라 다르다. 회복기에 매일 가는 곳(숙박·식사·스파)은 가깝게, 관광은 넓게 본다. +SEASON = {3: "spring", 4: "spring", 5: "spring", 6: "summer", 7: "summer", 8: "summer", + 9: "autumn", 10: "autumn", 11: "autumn", 12: "winter", 1: "winter", 2: "winter"} + TYPES = { "76": ("attraction", "10000"), "78": ("culture", "10000"), @@ -98,6 +101,164 @@ def call_all(env, op, extra, max_pages=6, rows=100): return total, got +def walk_min(m): + """도보 분. 80m/분(4.8km/h) 기준. 참고 사이트의 표기를 역산해 맞춘 값이다 + (135m→2분, 248m→3분, 297m→4분, 566m→7분).""" + return max(1, round(m / 80)) + + +def drive_min(km): + """차 이동 분. 직선거리 km x 1.2. 역시 역산값이다(25km→30분, 33km→40분).""" + return max(1, round(km * 1.2)) + + +def travel(m): + """이동 수단과 소요 시간. + 2km 까지는 걸을 수 있는 거리로 본다(약 25분). 그 위는 차·지하철이다. + 짧은 거리의 차 시간은 주차와 신호 때문에 의미가 없으므로 최소 5분으로 둔다.""" + if m is None: return None + if m <= 2000: return {"mode": "walk", "minutes": walk_min(m), "label": f"{walk_min(m)} min walk"} + mins = max(5, drive_min(m / 1000)) + return {"mode": "drive", "minutes": mins, "label": f"{mins} min by car"} + + +def fetch_overview(env, content_id, cache): + """detailCommon2 의 overview(설명문)와 homepage. locationBasedList2 는 주지 않는다. + 설명문이 없으면 카드가 이름과 주소뿐이라 사람이 고를 수 없다.""" + if content_id in cache: return cache[content_id] + try: + _, rows = call(env, "detailCommon2", {"contentId": content_id}, rows=1) + except Exception: + cache[content_id] = ("", ""); return cache[content_id] + if not rows: cache[content_id] = ("", ""); return cache[content_id] + r = rows[0] + ov = re.sub(r"<[^>]+>", " ", r.get("overview") or "") + ov = re.sub(r"\s+", " ", ov).strip() + hp = re.sub(r"<[^>]+>", " ", r.get("homepage") or "").strip() + hp = (re.search(r"https?://\S+", hp) or [None])[0] if hp else "" + cache[content_id] = (ov, hp or "") + return cache[content_id] + + +def fetch_image(env, content_id, cache): + """locationBasedList2 의 firstimage 가 비어 있을 때 detailImage2 로 한 번 더 찾는다. + 이미지 전용 오퍼레이션이라 목록 API 에 없는 사진이 여기 있다(도산공원 7장, 몽마르뜨공원 5장). + 실측: 사진 없던 38건 중 15건을 여기서 살렸다. 나머지 23건은 TourAPI 에 사진이 없다.""" + key = ("img", content_id) + if key in cache: return cache[key] + try: + _, rows = call(env, "detailImage2", {"contentId": content_id, "imageYN": "Y"}, rows=5) + except Exception: + cache[key] = ""; return "" + url = "" + for r in rows or []: + u = (r.get("originimgurl") or r.get("smallimageurl") or "").strip() + if u: url = u.replace("http://", "https://", 1); break + cache[key] = url + return url + + +def call_kor(env, op, extra, rows=10): + """국문 서비스(KorService2). 영문 항목에 사진이 없어도 국문 항목에는 있는 경우가 있다. + 같은 한국관광공사 사진이라 출처가 달라지지 않는다.""" + p = {"MobileOS": "ETC", "MobileApp": "INFINITH", "_type": "json", + "numOfRows": str(rows), "pageNo": "1", **extra} + url = f"{env['TOUR_API_BASE']}/KorService2/{op}?serviceKey={env['TOUR_API_KEY']}&" + urllib.parse.urlencode(p) + try: + with urllib.request.urlopen(url, timeout=25, context=ssl_ctx()) as r: + body = r.read().decode("utf-8", "replace") + if body.lstrip().startswith("<"): return [] + j = json.loads(body)["response"] + if j["header"].get("resultCode") != "0000": return [] + it = j["body"].get("items") + return [] if not it or it == "" else it["item"] + except Exception: + return [] + + +def korean_name(title): + m = re.search(r"\(([^)]+)\)\s*$", title or "") + return (m.group(1) if m else (title or "")).strip() + + +def fetch_image_kor(env, p): + """국문 서비스에서 같은 이름의 항목을 찾아 사진을 가져온다. 실측 23건 중 10건이 여기서 나왔다.""" + ko = korean_name(p.get("title")) + if not re.search(r"[가-힣]", ko): return "" + rows = [] + if p.get("lat"): + rows = call_kor(env, "locationBasedList2", + {"mapX": str(p["lng"]), "mapY": str(p["lat"]), "radius": "300", "keyword": ko}) + if not rows: rows = call_kor(env, "searchKeyword2", {"keyword": ko}) + key = ko.replace(" ", "") + for r in rows: + if key in (r.get("title") or "").replace(" ", ""): + u = (r.get("firstimage") or r.get("firstimage2") or "").strip() + if u: return u.replace("http://", "https://", 1) + return "" + + +def fetch_image_og(url): + """업체 공식 홈페이지의 대표 이미지(og:image). 업체가 스스로 올린 사진이라 목록에 쓰기에 무리가 없다. + 검색 결과 이미지를 긁어 쓰면 식당·블로그·언론사의 저작물이라 환자용 페이지에 올릴 수 없다.""" + if not url or not url.startswith("http"): return "" + try: + req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) + with urllib.request.urlopen(req, timeout=12, context=ssl_ctx()) as r: + head = r.read(120000).decode("utf-8", "replace") + base = r.geturl() + except Exception: + return "" + m = re.search(r']+(?:property|name)=["\']og:image["\'][^>]*content=["\']([^"\']+)', head, re.I) \ + or re.search(r']+content=["\']([^"\']+)["\'][^>]+(?:property|name)=["\']og:image', head, re.I) + if not m: return "" + u = m.group(1).strip() + if u.startswith("//"): u = "https:" + u + elif u.startswith("/"): + from urllib.parse import urlparse + pr = urlparse(base); u = f"{pr.scheme}://{pr.netloc}{u}" + return u if u.startswith("https://") else "" + + +def usable_image(url): + """실제로 이미지가 오는지 열어 본다. og:image 가 이미지가 아니거나(빈 content-type) + 인스타 CDN 처럼 핫링크를 403 으로 막는 경우가 있어 화면에서 빈 칸이 된다.""" + if not url: return False + try: + req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) + with urllib.request.urlopen(req, timeout=10, context=ssl_ctx()) as r: + return r.status == 200 and (r.headers.get("content-type") or "").startswith("image") + except Exception: + return False + + +def fetch_image_naver(env, p): + """마지막 폴백. Naver 이미지 검색 API. + 주의: 결과는 제3자 저작물이다. 내부 시연 목적으로만 쓰고, 공개 배포 전에는 + imageSource 가 'naver' 인 항목을 걷어내거나 라이선스가 있는 사진으로 교체한다. + 구글 HTML 크롤링 대신 이걸 쓰는 이유는 공식 API 라 차단되지 않고 결과가 일정해서다.""" + cid, sec = env.get("NAVER_CLIENT_ID"), env.get("NAVER_CLIENT_SECRET") + if not (cid and sec): return "" + ko = korean_name(p.get("title")) + if not ko: return "" + # 지역을 붙이면 정확도가 오르지만 결과가 아예 없는 경우가 있다. 넓혀 가며 시도한다. + plain = re.sub(r"\s*\(.*\)\s*", "", p.get("title") or "").strip() + for q in (f"{ko} 서울", ko, plain): + if not q: continue + qs = urllib.parse.urlencode({"query": q, "display": "3", "sort": "sim"}) + req = urllib.request.Request("https://openapi.naver.com/v1/search/image.json?" + qs, + headers={"X-Naver-Client-Id": cid, "X-Naver-Client-Secret": sec}) + try: + with urllib.request.urlopen(req, timeout=15, context=ssl_ctx()) as r: + items = json.loads(r.read().decode()).get("items", []) + except Exception: + continue + for it in items: + u = (it.get("link") or "").strip() + if u.startswith("https://"): return u + return "" + + def bucket(it): """분류코드로 범주를 정한다. None 이면 버린다.""" cat3 = (it.get("cat3") or "").strip() @@ -121,10 +282,15 @@ def clean(it, lat, lng): # tong.visitkorea.or.kr 은 https 로도 같은 파일을 준다(실측 확인). "image": (lambda u: u.replace("http://", "https://", 1) if u else None)( it.get("firstimage") or it.get("firstimage2") or None), + "imageSource": "tourapi" if (it.get("firstimage") or it.get("firstimage2")) else "", "tel": (it.get("tel") or "").strip() or None, "lat": ilat or None, "lng": ilng or None, "distanceM": round(float(dist)) if dist else ( round(haversine_km(lat, lng, ilat, ilng) * 1000) if ilat and ilng else None), + "travel": travel(round(float(dist)) if dist else ( + round(haversine_km(lat, lng, ilat, ilng) * 1000) if ilat and ilng else None)), + # detailCommon2 로 따로 채운다(locationBasedList2 는 설명문을 주지 않는다). + "overview": "", "homepage": "", # TourAPI 가 주지 않는 값. Google Places 승인 후 채운다. 지금은 비워 둔다. "rating": None, "reviewCount": None, "openingHours": None, } @@ -176,13 +342,59 @@ def main(): if c["lat"] is None: nocoord += 1; continue km = haversine_km(lat, lng, c["lat"], c["lng"]) if km > a.festival_km: continue - c.update(startDate=it.get("eventstartdate"), endDate=it.get("eventenddate"), - distanceKm=round(km, 1)) + sd = it.get("eventstartdate") or "" + c.update(startDate=sd, endDate=it.get("eventenddate"), + distanceKm=round(km, 1), month=(int(sd[4:6]) if len(sd) == 8 else None), + season=SEASON.get(int(sd[4:6]), "") if len(sd) == 8 else "") near.append(c) near.sort(key=lambda x: x["startDate"] or "") out["festivals"] = near[:a.per_type] print(f" festival API {total:>4}건 · 받음 {len(rows):>3} · 좌표없음 {nocoord} · {a.festival_km:.0f}km 이내 {len(near)}") + # 설명문은 항목마다 detailCommon2 를 한 번씩 부른다. 카드에 이름과 주소만 있으면 고를 수 없다. + cache: dict = {} + targets = [p for v in out["places"].values() for p in v] + out["festivals"] + print(f"\n 설명문 수집 {len(targets)}건", end="", flush=True) + for i, p in enumerate(targets): + if not p.get("id"): continue + ov, hp = fetch_overview(env, p["id"], cache) + p["overview"] = ov[:600] + p["homepage"] = hp + if not p.get("image"): + # 1) 영문 detailImage2 → 2) 국문 서비스 → 3) 업체 공식 홈페이지 og:image + # 1) 영문 detailImage2 → 2) 국문 서비스 → 3) 업체 홈페이지 og:image → 4) Naver 이미지 검색 + src = "" + img = fetch_image(env, p["id"], cache) + if img: src = "tourapi" + if not img: + img = fetch_image_kor(env, p); src = "tourapi-kor" if img else src + if not img: + cand = fetch_image_og(p.get("homepage") or "") + if cand and usable_image(cand): img, src = cand, "homepage" + if not img: + img = fetch_image_naver(env, p); src = "naver" if img else src + p["image"] = img or None + p["imageSource"] = src + if i % 20 == 0: print(".", end="", flush=True) + time.sleep(0.12) + got = sum(1 for p in targets if p["overview"]) + pic = sum(1 for p in targets if p.get("image")) + print(f" 완료 · 설명문 {got}/{len(targets)} · 사진 {pic}/{len(targets)}") + + # 도보 시간 구간별 건수. 화면의 필터 칩이 이 수를 쓴다. + allp = [p for v in out["places"].values() for p in v] + # 누적 기준이다. "15분 이내"는 5분 이내도 포함한다. 사람이 고르는 방식에 맞춘다. + def walk_upto(mins): + return sum(1 for p in allp if p.get("travel") and p["travel"]["mode"] == "walk" + and p["travel"]["minutes"] <= mins) + out["filters"] = { + "total": len(allp), + "walk5": walk_upto(5), + "walk15": walk_upto(15), + "walkAll": sum(1 for p in allp if p.get("travel") and p["travel"]["mode"] == "walk"), + "drive": sum(1 for p in allp if not p.get("travel") or p["travel"]["mode"] != "walk"), + } + out["meta"] = { "source": "한국관광공사 TourAPI " + env["TOUR_API_SERVICE"], "fetchedAt": time.strftime("%Y-%m-%dT%H:%M:%S"), diff --git a/supporters/src/data/factSheet.json b/supporters/src/data/factSheet.json index 02dbf6f..490910f 100644 --- a/supporters/src/data/factSheet.json +++ b/supporters/src/data/factSheet.json @@ -15,6 +15,9 @@ "locality": "강남구", "region": "서울특별시", "postalNote": "논현동 201-16", + "fullEn": "107 Bongeunsa-ro, Gangnam-gu, Seoul", + "postalCode": "06120", + "fullEnSource": "https://api.visitkorea.or.kr EngService2 contentid 3364779 (한국관광공사 영문 관광정보 등재)", "navigation": "서울시 강남구 봉은사로 1길 4 (논현동 201-14, 주차장 진입 기준)", "source": "https://www.viewclinic.com/viewis/direction/" }, diff --git a/supporters/src/data/medicalTourism.json b/supporters/src/data/medicalTourism.json index c78fd9b..aac79ad 100644 --- a/supporters/src/data/medicalTourism.json +++ b/supporters/src/data/medicalTourism.json @@ -6,10 +6,18 @@ "title": "Gangnam (강남)", "address": "Yeoksam-dong, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/08/1984608_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4970465429, "lng": 127.0281573537, "distanceM": 914, + "travel": { + "mode": "walk", + "minutes": 11, + "label": "11 min walk" + }, + "overview": "Gangnam Subway Station area is the prime district for those living south of the Hangang River. Gangnam-daero Avenue links Teheran-ro Road in the east to Jamsil and Sadang in the west. Kyobo Tower Crossroad connects Express Terminal to Noryangjin and west of Seoul. Hannam-daegyo Avenue in the north extends to the north of the Hangang River. A southward direction leads to metropolitan areas such as Seongnam, passing Yangjae and Bundang. Many people tend to gather at Gangnam Subway Station, as the location is geographically and commercially suitable as a meeting point for social gatherings, event", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -19,10 +27,18 @@ "title": "Samsung Gangnam (삼성 강남)", "address": "411 Gangnam-daero, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/98/2489498_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4963799255, "lng": 127.0265547405, "distanceM": 960, + "travel": { + "mode": "walk", + "minutes": 12, + "label": "12 min walk" + }, + "overview": "Samsung Gangnam is a flagship store designed as a playground for Samsung Electronics. Within the building are a photo spot, Galaxy flagship, auditorium, bespoke studio, and coffee shop, attracting numerous visitors. They are invited to appreciate media art through art objects and admire stunning views of skyscrapers on Gangnam-daero via a giant display with pleasure. ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -31,11 +47,19 @@ "id": "2989577", "title": "Hema Studio (헤마스튜디오)", "address": "20-10 Nonhyeon-dong, Gangnam-gu, Seoul", - "image": null, + "image": "https://hemastudio.com/og-image.png", + "imageSource": "homepage", "tel": null, "lat": 37.5134306323, "lng": 127.021493608, "distanceM": 1001, + "travel": { + "mode": "walk", + "minutes": 13, + "label": "13 min walk" + }, + "overview": "Hema Studio is a place that provides experience services for K-pop lovers and is located in Gangnam, Seoul. Hema Studio offers products that allow foreign tourists to record their favorite K-pop songs and shoot personal music videos. You can go through the entire process from recording to cover music video shooting with a 1:1 director. After cover recording and music video shooting are complete, the completed work can be put on a USB and shared with friends and family. It is also possible to upload to SNS such as YouTube and TikTok. Hema Studio is located in the downtown area of ​​Gangnam, so ", + "homepage": "http://www.hemastudio.com/", "rating": null, "reviewCount": null, "openingHours": null @@ -45,10 +69,18 @@ "title": "Sinsa-dong Garosu-gil Road (신사동 가로수길)", "address": "Sinsa-dong, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/50/2933550_image2_1.bmp", + "imageSource": "tourapi", "tel": null, "lat": 37.5215324916, "lng": 127.0227543748, "distanceM": 1852, + "travel": { + "mode": "walk", + "minutes": 23, + "label": "23 min walk" + }, + "overview": "The ginkgo tree-lined street (Sinsa-dong Garosu-gil) that runs from Sinsa Station (Subway Line 3) to Hyeondae High School is a popular, upscale street in Seoul. The street (also known as ‘artists' street’) has an eccentric flair thanks to its variety of charmingly decorated coffee shops, and designer stores. Garosu-gil is particularly popular in autumn when the golden ginkgo leaves begin to fall. Furthermore, with continous popularity, it has become one of the most attractive film locations in the city.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -57,11 +89,19 @@ "id": "264106", "title": "Seolleung and Jeongneung Royal Tombs [UNESCO World Heritage] (서울 선릉과정릉) [유네스코 세계유산]", "address": "1 Seolleung-ro 100-gil, Gangnam-gu, Seoul", - "image": null, + "image": "https://dbscthumb-phinf.pstatic.net/2472_000_1/20160609122018262_YJWQWM4DH.jpg/comd4_8_i52.jpg?type=m4500_4500_fst_n", + "imageSource": "naver", "tel": null, "lat": 37.5074206801, "lng": 127.0471803291, "distanceM": 1953, + "travel": { + "mode": "walk", + "minutes": 24, + "label": "24 min walk" + }, + "overview": "Seolleung and Jeongneung Royal Tombs are located near COEX in Gangnam. It comprises two tombs: Seolleung Royal Tomb, which houses the remains of King Seongjong (1457-1495, r. 1470-1495) and his wife Queen Jeonghyeon (1462-1530) of the Joseon dynasty (1392-1897), and Jeongneung Royal Tomb, which houses King Jungjong (1488-1544, r. 1506-1544), Seongjong’s son. The Seolleung and Jeongneung Royal Tombs History Center details the historical significance of the tomb, while the complex also serves as a park within the city.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -70,11 +110,19 @@ "id": "264444", "title": "Dosan Park (도산공원)", "address": "20, Dosan-daero 45-gil, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/44/1567744_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5214632538, "lng": 127.0338117034, "distanceM": 1976, + "travel": { + "mode": "walk", + "minutes": 25, + "label": "25 min walk" + }, + "overview": "Located in Sinsa-dong, Seoul, Dosan Park, a neighborhood park, was built in 1973 to pay tribute to Dosan Ahn Chang-ho’s patriotism. Dosan Ahn Chang-ho’s tomb was moved here from Manguri Public Cemetery as well as his wife, Lee Hyeryen, whose tomb was moved from Los Angeles. The tribute was extended by naming the boulevard from Cheongdam-dong to Nonhyeon-dong, as Dosan-daero. Visitors can find a bronze statue, monument with quotations, epitaph headstone and more within the park. Commemoration event is held on March 10th of every year.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -83,11 +131,19 @@ "id": "1013448", "title": "Jamwon Hangang Park (잠원한강공원)", "address": "221-124 Jamwon-ro, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/29/3515029_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.5207129541, "lng": 127.0122664645, "distanceM": 2101, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Jamwon Hangang Park is a public recreation area on the Hangang River. Nearby attractions include athletic facilities (running tracks, soccer fields, basketball courts, etc.), various water sports facilities, and an 8.2-kilometer inline skating path. A bicycle path along the Hanfgang River, an outdoor swimming pool in summer, and a snow sledding center in winter are the most frequently used ones by may citizens. Jamwon was once a mulberry field, so there is also a thematic nature learning center that depicts the life of the silkworm.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -96,11 +152,19 @@ "id": "2035459", "title": "Montmartre Park (몽마르뜨공원)", "address": "59 Banpo-daero 37-gil, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/19/755619_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4955435016, "lng": 127.0037401743, "distanceM": 2194, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Montmartre Park, situated above Seorae Village, earns its name due to the significant number of French residents in the vicinity. This small park exudes an atmosphere of art and romance, fitting its namesake. Adorned with poems and sculptures contributed by French poets and artists, the park also features busts depicting renowned figures like Vincent Van Gogh, Paul Gauguin, and Pablo Picasso. Towards the park's conclusion, Nue Bridge connects it to the Seoripul Neighborhood Park.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -109,11 +173,19 @@ "id": "3340158", "title": "Seoul Wave Art Center (서울웨이브아트센터)", "address": "145-35 Jamwon-ro, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/30/3096830_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.518440907, "lng": 127.007297537, "distanceM": 2197, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Seoul Wave Art Center is located within Jamwon Hangang Park, and focuses on promoting the relationship between the sky and earth, people and nature, and people and people. The art center opened in 2020 and has continued to host a range of new exhibitions.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -123,10 +195,18 @@ "title": "Gilsang Ceramics (길상도예)", "address": "15-9 Gangnam-daero 39-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/50/2946050_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.48583681, "lng": 127.0324406141, "distanceM": 2215, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The pottery workshop experienced by BTS It is a famous pottery workshop for ARMY as a place where BTS experienced in ‘RUN BTS’. Jimin made cups for V, Jin for Jung kook, and V for SUGA. You can design and make cups, vases, plates, water bottles, etc. with a potter's wheel and handbuilding. It's also fun to make it after the works of BTS members. ", + "homepage": "https://cafe.naver.com/gilsangdoye", "rating": null, "reviewCount": null, "openingHours": null @@ -135,11 +215,19 @@ "id": "3107994", "title": "KstarROAD 한류스타거리 (KstarROAD Hallyu Star Road)", "address": "394, Apgujeong-dong, Gangnam-gu, Seoul", - "image": null, + "image": "https://i.pinimg.com/474x/e1/9d/6a/e19d6a58ed4d44b82377a92195affe3a.jpg", + "imageSource": "naver", "tel": null, "lat": 37.5253320799, "lng": 127.024415227, "distanceM": 2261, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The K-Star ROAD is a place to meet the stories of celebrities who were at the forefront of the K-Wave phenomenon. The road features art toy statues inspired by K-Pop bands, such as SNSD, EXO, and TVXQ, while terminals next to shops help you find the fashion shops and restaurants frequented by celebrities. Moreover, the schools attended by the celebrities, houses in which they used to live, and other spots that capture their stories can also be found on this street.", + "homepage": "https://korean.visitseoul.net/hallyu/K-star-ROAD-%EA%B0%95%EB%82%A8-%ED%95%9C%EB%A5%98%EC%8A%A4%ED%83%80%EA%B1%B0%EB%A6%AC_/15768", "rating": null, "reviewCount": null, "openingHours": null @@ -149,10 +237,18 @@ "title": "Jennyhouse (제니하우스)", "address": "56 Seolleung-ro 146-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/69/3474069_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5213912279, "lng": 127.0442774197, "distanceM": 2476, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Step into Jennyhouse, Korea’s top luxury beauty salon, for an unforgettable hair and makeup transformation. Renowned for its exceptional service and artistry, Jennyhouse is where celebrities like Son Ye-jin, Han Ji-min, and Suzy achieve their iconic looks. Upon booking a reservation, clients can choose from a range of services tailored to their style and needs. Whether it’s a glamorous red-carpet makeover, a trendy K-beauty hair transformation, or elegant wedding styling, Jennyhouse's team of 80 expert artists ensures a personalized experience. Expect cutting-edge techniques, top-t", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -162,10 +258,18 @@ "title": "Hyanggieok (향기억)", "address": "23 Seolleung-ro 157-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/44/2946044_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5261572277, "lng": 127.0379584155, "distanceM": 2601, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Making the unique perfume in the world It is a workshop where you can create your own personalized perfume. A number of famous celebrities such as MOMOLAND's JOOE and CHUNG HA have visited. In addition to perfume, diffuser and candle one-day classes are also available. You can also purchase a variety of scented products such as fabric perfume and pet deodorant products.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -174,11 +278,19 @@ "id": "2037327", "title": "Seorae Village (서래마을)", "address": "Banpo-dong, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/01/862801_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.496343309, "lng": 126.9981601041, "distanceM": 2606, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Seorae Village is located in between Banpo 4-dong and Bangbaebon-dong in Seocho-gu, Seoul. Seorae Village took its form as a French neighborhood when French residents moved to the area after Ecole Francaise de Seoul, a school for French residents in Korea, was established here in 1985. According to 2008 census, about half of the total 1,000 French citizens residing in Korea were registered to be living in Seorae Village. The area naturally took shape as a global neighborhood as many international residents settled at Seorae Village much thanks to the strong presence of French residents. In add", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -188,10 +300,18 @@ "title": "Apgujeong Rodeo Street (압구정 로데오거리)", "address": "Sinsa-dong, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/44/3109344_image2_1.JPG", + "imageSource": "tourapi", "tel": null, "lat": 37.5268766055, "lng": 127.0388971983, "distanceM": 2710, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Apgujeong Rodeo Street is a cultural street in Apgujeong full of luxury brands and multi-shops. It is a popular destination with significant foot traffic thanks to its convenient shopping opportunities, famous cafés and restaurants, and shops with unique interior design. This street is the place to experience Korean fashion and cultural trends. Nearby tourist sites include Cheongdam Fashion Street and Garosu Street of Sinsa-dong.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -200,11 +320,19 @@ "id": "1013413", "title": "Some Sevit (세빛섬)", "address": "2085-14, Olympic-daero, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/10/3515810_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.5111915303, "lng": 126.9951432925, "distanceM": 2778, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Some Sevit is a culture complex made up of three man-made floating islands near the southern end of Banpo Bridge. The islands were created with the theme of \"flowers of the Hangang River\" and represent the view, life, and the earth, as well as a flower in various stages of life. The largest island, 'Some Gavit' symbolizes the view and takes the form of a flower in full bloom. It is a multi-functional cultural facility that can be used as a venue for performances, international conferences, exhibitions, and more. The second island, 'Some Chavit' looks like a flower bud, an image of life. A rang", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -214,10 +342,18 @@ "title": "Banpo Bridge Rainbow Fountain (반포대교 달빛무지개분수)", "address": "647 Banpo-dong, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/46/3515046_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5076780054, "lng": 126.9926825046, "distanceM": 2926, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Rainbow Fountain plunges 20 meters into the water on both side of Banpo Bridge over the Hangang River. When the sun goes down, 200 lights illuminate the fountain as it sends out dancing, rainbow-colored jets of water in the air in synchronization with music. The fountain boasts spectacular views from the hills, the Hangang River observation deck, and the moon-shaped Moonlight Square. Banpo Bridge Rainbow Fountain operates every day from April to October, four to six times a day for 20 minutes.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -227,10 +363,18 @@ "title": "Cheongdam Fashion Street (청담패션거리)", "address": "Cheongdam-dong, Gangnam-gu, Seoul-si", "image": "https://tong.visitkorea.or.kr/cms/resource/82/2728682_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5259073966, "lng": 127.0457632671, "distanceM": 2944, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The street from the Cheongdam Station intersection to Galleria Department Store is lined with luxury brand stores and dubbed as “Cheongdam Fashion Street.\" Often frequented by celebrities, the area became a popular tourist destination for hallyu fans. Inside the alleys are famous restaurants, and with art galleries and boutiques popping up within the area, the street has gained a reputation as a cultural shopping street.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -239,11 +383,19 @@ "id": "264594", "title": "Seoul Bongeunsa Temple (봉은사 (서울))", "address": "531 Bongeunsa-ro, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/35/2652135_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5158782211, "lng": 127.0577485719, "distanceM": 3118, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Once known as Gyeonseongsa Temple, Bongeunsa Temple is located north of COEX, and was constructed in the 10th year of Silla King Weongseong’s reign (794). In 1498, Queen Jeonghyeon refurbished Gyeonseongsa Temple and renamed it Bongeunsa Temple. Originally located near the Royal Tomb of King Seongjong, the temple was transferred to its current location during Joseon King Myeongjong’s reign. The temple is home to 3,479 Buddhist scriptures of 13 types, including the works of Kim Jeong-hee. The Buddhist ceremony called Jeongdaebulsa is held on the ninth day of the eighth month of the lunar calend", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -253,10 +405,18 @@ "title": "Maeheon Citizen's Forest (매헌시민의 숲)", "address": "99, Maeheon-ro, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/66/2668466_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.473038377, "lng": 127.0369572316, "distanceM": 3691, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Maeheon Citizen's Forest, located near Yangjae Tollgate, was created in anticipation of the Seoul Asian Games in 1986 and the 24th Olympic Games in 1988. The forest provides a scenic habitat for 94,800 trees of 43 different species including pine, zelkova, purple bloom maple, horse chestnut, and nut pine. These trees are rarely seen in cities and the park is a popular date spot for couples. In the fall, the trees in the park bear an abundance of persimmons and quinces. Amenities and facilities include an outdoor wedding hall, walking course, basketball court, volleyball court (also used for fo", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -265,11 +425,19 @@ "id": "264131", "title": "Yongsan Family Park (용산가족공원)", "address": "185, Seobinggo-ro, Yongsan-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/75/566475_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.520106972, "lng": 126.9845717812, "distanceM": 4001, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Visitors to Yongsan Family Park can enjoy a relaxing time at a big grassy field beside a refreshing pond and well-organized walking paths. Yongsan Family Park spans an area of roughly 89,256.20 ㎡ in what was a section of the former golf course of the Eighth US Army Division. The park is comprised of various facilities such as a 2km-walking path, a natural education site, and Taegeukgi Park. Visitors can watch and feed pigeons and wild pheasants living at the park.", + "homepage": "http://parks.seoul.go.kr", "rating": null, "reviewCount": null, "openingHours": null @@ -278,11 +446,19 @@ "id": "1887247", "title": "Hangang River (한강)", "address": "257 Gangbyeonbuk-ro, Seongdong-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/91/3509791_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.5389280323, "lng": 127.0416216085, "distanceM": 4034, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Hangang River is a iconic river in Korea that crosses Seoul from north to south. Various parks and cultural facilities are located along the river, attracting numerous people to enjoy leisure and relaxation. Many people enjoy walking, biking, and jogging along the river. Water sports such as fishing, kayaking, and sailing are also popular, and the night view of the river from a cruise ship makes it even more beautiful. Events such as concerts, drone festivals, and fireworks displays are also a must-see. ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -292,10 +468,18 @@ "title": "Itaewon Antiques Street (이태원 앤틱 가구 거리)", "address": "109-1 Bogwang-ro, Yongsan-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/81/1020781_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5326695793, "lng": 126.9944566364, "distanceM": 4126, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Itaewon Antiques Street was formed around the late 1960s, when a group of antique dealerships from Asia, Europe, and North America settled in the district. This 1km-long street is home to antique dealers offering antique sofa, chairs, and tables. Some shops also offer antique decorations, accessories, and clothing. It is a famous shopping district with its own unique ambience from that of Seoul. During spring and autumn, Itaewon Antique Festival takes place, allowing visitors to shop and enjoy cultural performances.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -305,10 +489,18 @@ "title": "Waterworks Museum (수도박물관)", "address": "27, Wangsimni-ro, Seongdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/77/1570777_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5398751565, "lng": 127.0422909651, "distanceM": 4153, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Ttukseom Water Purification Plant (Waterworks Museum and Slow Sand Filtration Basin) was completed in August 1908 as the first water purification plant ever built in Korea. In 2008, it celebrated 100 years of history with the opening of the Waterworks Museum, which showcases the history and value of Seoul's public waterworks. The museum was recognized for its modern architectural design and designated Tangible Cultural Asset of Seoul No.72.", + "homepage": "https://arisu.seoul.go.kr/arisumuseum/", "rating": null, "reviewCount": null, "openingHours": null @@ -320,10 +512,18 @@ "title": "Kukkiwon (World Taekwondo Headquarters) (국기원(세계태권도본부))", "address": "(Kukkiwon), 32, Teheran-ro 7-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/77/919177_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5019710091, "lng": 127.0302792433, "distanceM": 546, + "travel": { + "mode": "walk", + "minutes": 7, + "label": "7 min walk" + }, + "overview": "Established in 1972, Kukkiwon serves as the headquarters of World Taekwondo. The organization strives to promote the Korean cultural heritage of Taekwondo across the world and set the culture of Taekwondo. To that end, it provides Taekwondo instructor training, undertakes research and development of Taekwondo techniques, and hosts the World Taekwondo Hanmadang. The nearby Kukkiwon Memorial Hall collects and exhibits artifacts related to Taekwondo’s history.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -332,11 +532,19 @@ "id": "268118", "title": "LG Arts Center (LG아트센터)", "address": "(LG Arts Center Seoul), 136, Magokjungang-ro, Gangseo-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/48/2024248_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5019766908, "lng": 127.037334157, "distanceM": 1111, + "travel": { + "mode": "walk", + "minutes": 14, + "label": "14 min walk" + }, + "overview": "LG Arts Center is a cultural complex space designed by Tadao Ando, a world-renowned architect. Its architectural excellence and design have won great acclaim. The main facilities contain performance halls, Art Lounge, and Studio. The LG SIGNATURE Hall, a multipurpose performance hall, has a capacity of 1,300. Its state-of-the-art facilities and sound design have drawn many visitors and performances to the complex.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -346,10 +554,18 @@ "title": "Seoul Center for National Intangible Cultural Asset (서울국가무형문화재전수회관)", "address": "406, Bongeunsa-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/39/683839_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5102008674, "lng": 127.0446443698, "distanceM": 1805, + "travel": { + "mode": "walk", + "minutes": 23, + "label": "23 min walk" + }, + "overview": "Created by the government to hand down traditions and preserve important, intangible cultural assets, the center supports cultural masters in the training of their pupils and their efforts to promote Korean traditional culture to the general public. The center houses 8 groups that represent the music field. Serving not only as a training ground for those specializing in the arts, the center also seeks to reach out to the general public through regular programs and recitals. Musicians also participate in musical conferences, events and performances on a national and international level. There a", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -359,10 +575,18 @@ "title": "Yearimdang Art Hall (예림당아트홀)", "address": "337, Eonju-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/34/1837534_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4978884026, "lng": 127.0443114151, "distanceM": 1855, + "travel": { + "mode": "walk", + "minutes": 23, + "label": "23 min walk" + }, + "overview": "Yearimdang Art Hall is a children’s theater that opened in March 2011. A joint project of Yearimdang publishing company and PMC Production, the art hall is a mid-sized theater with 439 seats divided into two floors. The first floor consists of VIP sets and S-class seats that allow for more interaction with the actors on stage and access to surprise events during the performances. Seats on the second floor (A-class) offer an affordable, bird’s-eye-view of the stage. The seats are designed to fit children’s body, while providing parents with much needed rest.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -372,10 +596,18 @@ "title": "Korea Electric Power Corporation (KEPCO) Art Center (한전아트센터 공연장)", "address": "60, Hyoryeong-ro 72-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/99/3109799_image2_1.JPG", + "imageSource": "tourapi", "tel": null, "lat": 37.4856450857, "lng": 127.0279688042, "distanceM": 2158, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The KEPCO Art Center is a cultural complex that provides opportunities to experience a diverse range of arts and culture. The Grand Theater's performances range from musicals and operas to classical and pop music. It offers excellent works that have undergone a rigorous selection process. The center's gallery, electricity museum and sports club are all located in one space, offering a one-stop exploration. ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -384,11 +616,19 @@ "id": "1382730", "title": "Hallym University of Graduate Studies (한림국제대학원대학교)", "address": "405, Yeoksam-ro, Gangnam-gu, Seoul", - "image": null, + "image": "https://scs-phinf.pstatic.net/MjAyNDAyMjhfMTY1/MDAxNzA5MTA3MTk4MzU0.X3JpoM6ynJcsJ_WBtjj2I0b-f0j0obxkrM2R3EtUmmog.V6oNbSuYphTClOdiSvWyjUvnwVPsrzAVluJ_YbsYmy0g.PNG/3042.png?type=w800", + "imageSource": "naver", "tel": null, "lat": 37.5009992789, "lng": 127.0513884609, "distanceM": 2351, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Founded in 2004 by Ilsong Educational Foundation, Hallym University of Graduate Studies is a private college located at 405, Yeoksam-ro, Gangnam-gu. Originally, it was founded as an international graduate college of Hallym University in 1997, but it has separated from Hallym University as of 2004.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -398,10 +638,18 @@ "title": "Park Ryu Sook Gallery (박여숙화랑)", "address": "461, Apgujeong-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/33/683733_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5252491662, "lng": 127.0472214864, "distanceM": 2969, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Soon after its opening in 1983, the Park Ryu Sook Gallery moved to Cheongdam-dong, an uncharted territory back in 1988. Ever since, the gallery has played a significant role in turning the region into one of the most representative art places in Korea. The Park Ryu Sook Gallery mainly deals with modern art, and contributes to the development of Korea's modern art scene by recruiting and supporting talented rookies in the field, and by introducing artwork of major modern artists from abroad. Moreover, the gallery works to promote Korean art worldwide by joining major art fairs such as the Chica", + "homepage": "https://m.blog.naver.com/ryusook1983", "rating": null, "reviewCount": null, "openingHours": null @@ -410,11 +658,19 @@ "id": "1312802", "title": "Hangaram Art Museum in Seoul Arts Center (예술의전당 한가람미술관)", "address": "2406, Nambusunhwan-ro, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/28/1807828_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4793094549, "lng": 127.0137702756, "distanceM": 3032, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Hangaram Art Museum, located in the left wing of the Seoul Arts Center, displays a unique exhibition of formative arts. Established in 1990, the museum has a total area of 15,540 ㎡ and contains 6 exhibition halls (including one for oversized artwork), a storage area, and an art shop. The building features a lighting system that controls the humidity and temperature and is equipped with a luminous ceiling system that captures natural sunlight and feeds it into the museum, allowing visitors to enjoy a brightly lit viewing area. The Art Square in front of the museum houses a wide range of exclusi", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -424,10 +680,18 @@ "title": "COEX Aquarium (코엑스 아쿠아리움)", "address": "513 Yeongdong-daero, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/83/3081283_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5118092746, "lng": 127.0591318945, "distanceM": 3091, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The COEX Aquarium comprises 183 display tanks and 90 breeding tanks with 3,500 tons of water volume, making it a large-scale aquarium. It houses 40,000 sea creatures of 650 different species, exhibited in 16 themed zones. In particular, the highest number of sharks and the largest variety of species in Korea are living in this aquarium. Over 20 rest areas located throughout the aquarium, as well as an open-top water tank releasing anions make this tourist site in the heart of Gangnam a perfect healing place for local and international visitors.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -437,10 +701,18 @@ "title": "Starfield Library (별마당도서관)", "address": "513, Yeongdong-daero, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/17/2507817_image2_1.JPG", + "imageSource": "tourapi", "tel": null, "lat": 37.5118092746, "lng": 127.0591318945, "distanceM": 3091, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Located in the middle of COEX Central Plaza, Starfield Library offers visitors a perfect reading space. The two-story library has 13-meter-tall bookshelfs and soft lights to ease the eyes as well as various types of tables with electric plugs for those with laptops. With more than 50,000 books ranging from literature to hobbies as well as over 400 types of magazines, visitors are welcome to find pleasure in reading and relax.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -449,11 +721,19 @@ "id": "268208", "title": "Convention and Exhibition Center (COEX) (한국종합무역센터(코엑스))", "address": "513, Yeongdong-daero, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/62/2005262_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5117453937, "lng": 127.0591541159, "distanceM": 3092, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Convention and Exhibition Center (COEX) was established on September 7, 1988 as a large-scale business town for domestic and overseas businessmen. Business operations can be managed easily as assembly halls, exhibition halls, the Korean City Air Terminal, InterContinental Hotel, and Hyundai Department Store are gathered in one spot. A 57-story building contains 20 trade organizations including the Korea International Trade Association (KITA), as well as 250 companies and financial institutions. Convention and Exhibition, which houses three specialized exhibition halls and permanent exhibit", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -463,10 +743,18 @@ "title": "COEX Artium (코엑스아티움)", "address": "513, Yeongdong-daero, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/72/2005272_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5118148298, "lng": 127.0591402265, "distanceM": 3092, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Established by Korea International Trade Association and COEX, COEX Artium is a spacious muscial performance hall with over 800 seats. High quality and diverse musical or theatrical performances are held year-round to satisfy both Korean and international visitors. Foreign language services (English, Japanese, and Chinese) are also available. It has the Trade Promotion Exhibition Hall. Near COEX Artium are many performance halls such as COEX Art Hall (184 seats), Auditorium (1058 seats), Convention Hall (7,000 seats), ang Grand Conference Room (450 seats), making the COEX area a main place for", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -476,10 +764,18 @@ "title": "Ktown4u COEX (케이타운포유 코엑스)", "address": "513 Yeongdong-daero, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/73/3305173_image2_1.png", + "imageSource": "tourapi", "tel": null, "lat": 37.5119175967, "lng": 127.059217995, "distanceM": 3102, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Ktown4u COEX is a K-culture complex located in the bustling COEX district. The center offers everything a hallyu fan could wish for, from K-pop to beauty, fashion, and even K-lifestyle. Each of the three floors focuses on a different way to experience K-culture, with the second floor offering sales of diverse goods, the third floor operating as an academy for learning K-pop dances and songs, and the fourth floor being an event space to facilitate  communication between fans and artists.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -489,10 +785,18 @@ "title": "Korea Culture House (KOUS) (한국문화의집)", "address": "12-9, Teheran-ro 92-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/84/1837284_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5068182113, "lng": 127.060476358, "distanceM": 3123, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Operated by Korea Cultural Heritage Foundation, the Korea Culture House (KOUS), similar to the Korea House in Gangbuk area, opened in Daechi-dong, Gangnam. Tourists visiting Korea and international students residing in Korea can experience and learn Korea's traditional culture at this educational space.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -502,10 +806,18 @@ "title": "Simsan Cultural Center (심산기념문화센터)", "address": "55, Sapyeong-daero, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/71/1865771_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4988456583, "lng": 126.9904940651, "distanceM": 3179, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Simsan Cultural Center was established to commemorate the Confucianism and patriotic spirit of Simsan Kim Chang-Suk. It also offers educational and training programs to the local community for developing life skills while adding to the overall quality of life.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -514,11 +826,19 @@ "id": "1802823", "title": "S.J. Cho Korean Paper Art Gallery (조수정 한지그림 갤러리)", "address": "14, Teheran-ro 92-gil, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/43/2024243_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5070904146, "lng": 127.0611762867, "distanceM": 3187, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The S.J. Cho Korean Paper Art Gallery is dedicated to hanji (traditional Korean paper) art and was the first of gallery in Korea to focus on this traditional medium. It is also the center of the Korean Hanji Art Organization, which has helped popularize hanji art over the past 30 years. Visitors can browse through hanji art in the gallery, enjoy traditional tea in the café, or look out at Bukhansan Mountain from the rooftop. The experience hall is located in the basement, where visitors can learn more about hanji art, or even try their hand at making their own.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -527,11 +847,19 @@ "id": "268071", "title": "Seoul Arts Center (예술의전당)", "address": "2406 Nambusunhwan-ro, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/82/4089582_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.4785261578, "lng": 127.0107150202, "distanceM": 3214, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Seoul Arts Center is the representative art complex of Korea. It is comprised of the Opera House, Concert Hall, Art Gallery, Calligraphy Museum, Art Material Hall, and an outdoor stage. You can enjoy various performances and exhibitions all in one site. The Opera House and Concert Hall consist of a total of five performance halls offering an average of 800 performances ever year, whereas the Art Gallery and Calligraphy Museum has seven exhibition halls providing various exhibitions throughout the year. The outdoor stage also provides various genres of performances all year round.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -540,11 +868,19 @@ "id": "268140", "title": "National Gugak Center (국립국악원)", "address": "2364 Nambusunhwan-ro, Seocho-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/46/3540546_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.4778373158, "lng": 127.0088596528, "distanceM": 3353, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The National Gugak Center is the governing body established to preserve and promote traditional Korean performing arts. The center can accommodate every type of traditional performing arts, such as palace music, court music, and all other genres including major productions of changgeuk (Korean musical drama). Originally opened in Busan in 1951, the center moved to its current location in Seoul in 1987. The center also opened branch locations in Namwon, Jindo, and Busan in 1992, 2004, and 2008 respectively.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -553,11 +889,19 @@ "id": "1962734", "title": "National Hangeul Museum (국립한글박물관)", "address": "139, Seobinggo-ro, Yongsan-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/21/1954321_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5210429011, "lng": 126.9804832384, "distanceM": 4374, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The National Hangeul Museum was established to preserve, spread, and develop the Korean alphabet, Hangeul. The museum showcases the history and value of Korean orthography, Korean’s most-valued cultural asset, through exhibitions, activities, and education. Occupying over 11,322 ㎡, the museum has one basement level and three ground levels, along with an outdoor grass field and rest area perfect for cultural events, exhibits, and education. The museum is comprised of the Hangeul library on the first floor, a permanent exhibition hall, ㅎ Café, and cultural product shop on the second floor, and a", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -566,11 +910,19 @@ "id": "268217", "title": "Leeum, Samsung Museum of Art (삼성미술관 리움)", "address": "60-16, Itaewon-ro 55-gil, Yongsan-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/46/632846_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5385800812, "lng": 126.9987921858, "distanceM": 4417, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Leeum, Samsung Museum of Art, exhibits traditional and modern art works by Korean and international artists. The museum itself is just as fascinating as the art works on display, since the museum's three buildings were designed by internationally renowned architects Mario Botta, Jean Nouvel, and Rem Koolhaas. MUSEUM 1 houses traditional Korean art, such as calligraphy, paintings, ceramic arts, and metal craftwork, while MUSEUM 2 displays modern and contemporary art by both Korean and international artists.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -580,10 +932,18 @@ "title": "aT Center (에이티센터)", "address": "27, Gangnam-daero, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/26/621926_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4664808435, "lng": 127.0391127763, "distanceM": 4444, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "aT Center is a convention center where exhibitions, conventions, and business trades all take place. Cutting-edge exhibition and conference rooms are suitable for various types of exhibitions, seminars, banquets, events, performances and more. To support successful events, aT Center provides simultaneous interpretation services, an audio-visual system, cold storage and a trade information service. The center is a one-stop venue for trade, comprised of an export firm hall, export promotion hall and other related facilities, offering a permanent exhibition of promised exported items, promotion, ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -593,10 +953,18 @@ "title": "Blue Square (블루스퀘어)", "address": "294, Itaewon-ro, Yongsan-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/77/1805577_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5408548829, "lng": 127.002458454, "distanceM": 4475, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Blue Square is a multipurpose performance venue located in Hannam-dong. It includes Shinhan Card Hall, a performance hall dedicated to musicals with 1,776 seats, and Mastercard Hall, a multipurpose performance hall with 1,400 seats. Blue Square also includes the Book Park, which has a collection of nearly 75,000 books, and a café with a terrace that looks toward the Namsan Mountain. Many visitors come to the Blue Square to see its collection of popular musicals and other performances.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -606,10 +974,18 @@ "title": "Childrens Museum of the National Museum of Korea (국립중앙박물관 어린이박물관)", "address": "137, Seobinggo-ro, Yongsan-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/06/1805106_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5240675476, "lng": 126.9803609412, "distanceM": 4531, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Children’s Museum of the National Museum of Korea is an experience-oriented museum where children can see, touch, and feel history through hands-on programs and games. The permanent exhibition hall displays replicas of historical items so children can learn about Korea’s cultural heritage in a fun and interactive way. Children can also experience the lifestyle and wisdom of the past through experience programs.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -619,10 +995,18 @@ "title": "Seongsu Museum (성수미술관)", "address": "39 Seongsuil-ro 8-gil, Seongdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/41/2946041_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5458358003, "lng": 127.0548174333, "distanceM": 5234, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "rom drawing to coloring This is a canvas drawing cafe where Yuna of ITZY visited and experienced art. It is decorated as a cultural living space where you can draw and color. Drawing tools such as sketches, acrylic paints, and brushes are provided. It is also interesting that there is a mobile phone holder so that you can capture your drawing as a time-lapse.", + "homepage": "https://seongsumuseum.com", "rating": null, "reviewCount": null, "openingHours": null @@ -634,10 +1018,18 @@ "title": "Nonhyeon Furniture Street (논현가구거리)", "address": "106 Hakdong-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/18/1920618_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5111836894, "lng": 127.0225185784, "distanceM": 735, + "travel": { + "mode": "walk", + "minutes": 9, + "label": "9 min walk" + }, + "overview": "Nonhyeon Furniture Street, extending over 900 meters from Nonhyeon Station to Hakdong Station on the Seoul Subway, is renowned for its dense aggregation of furniture stores. Established as a dedicated furniture street in 1970, it now features showrooms and sales outlets from over 100 furniture companies. This destination allows visitors to browse and compare an extensive variety of furniture in one convenient location, including design furniture, craft furniture, kitchen sets, office furnishings, and imported pieces. Additionally, it hosts the annual Gangnam Design Week, a prominent event show", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -647,10 +1039,18 @@ "title": "T1 (T1)", "address": "627 Seolleung-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/87/2946987_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.512511677, "lng": 127.0428028051, "distanceM": 1757, + "travel": { + "mode": "walk", + "minutes": 22, + "label": "22 min walk" + }, + "overview": "Perfect place for T1 fans It is a space and goods shop for fans of the LoL pro game team T1 who enjoy e-sports. A life-sized figure of the legendary pro gamer Faker is at the entrance, and trophies won in previous LoL-related competitions are on display. It is a place where you can enjoy T1 up close by engraving your name on the same uniform as the players.", + "homepage": "https://shop-t1.gg/", "rating": null, "reviewCount": null, "openingHours": null @@ -660,10 +1060,18 @@ "title": "Central City (센트럴시티)", "address": "176, Sinbanpo-ro, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/09/1255009_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.505372917, "lng": 127.0038037796, "distanceM": 1922, + "travel": { + "mode": "walk", + "minutes": 24, + "label": "24 min walk" + }, + "overview": "Connected to the Express Bus Terminal Station, Central City is a large lifestyle cultural complex. With in the City are a department store, movie theater, bus terminal, hotel, and shopping malls. Especially, Familie Station & Garden is home to beauty salons, restaurants and coffe shops that are famous and unique. One can also explore attractions such as the Express Bus Terminal Underground Shopping Mall and Banpo Wholesale Flower Market, enriching the experience of the area.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -673,10 +1081,18 @@ "title": "CAOLION Cosmetics (카오리온)", "address": "8, Apgujeong-ro 50-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/40/1859140_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5277792626, "lng": 127.0380139198, "distanceM": 2767, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Established in 1995, CAOLION Cosmetics has been making hypoallergenic cosmetics for sensitive skin for 18 years. The company launched natural cosmetics for the first time with a 3-free principle: pigment-free, fragrance-free, and alcohol free. At the present, the company has developed products that are exclude up to 17 adverse ingredients such as preservatives and mineral fibers. CAOLION was the first Korean brand to enter into LVMH (Louis Vuitton Monët Hennessy) Group's global cosmetics retail chain SEPHORA after being recognized as a quality natural cosmetic product for senstive skin after o", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -686,10 +1102,18 @@ "title": "10 Corso Como Cheongdam Branch (10꼬르소꼬모 청담점)", "address": "416, Apgujeong-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/71/2778971_image2_1.png", + "imageSource": "tourapi", "tel": null, "lat": 37.5269655478, "lng": 127.0424468728, "distanceM": 2872, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "A trendy select shop frequented by celebrities It is a trendy select shop with a restaurant and cafe. BLACKPINK JENNIE uploaded a restaurant on Instagram, which became a hot topic. It is a place where colorful ceiling decorations and sensuous interiors stand out, and the photo point is the wall decorations that are said to have been made by hand. There are a variety of products from books to interior accessories and clothes, and pop-up stores of various brands are often opened. Thanks to this, it is known as a sacred place for celebrities and fashion people who are sensitive to trends.", + "homepage": "https://www.instagram.com/10corsocomoseoul/", "rating": null, "reviewCount": null, "openingHours": null @@ -699,10 +1123,18 @@ "title": "Hyundai Department Store Trade Center (현대백화점 무역센터점)", "address": "517 Teheran-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/01/3490601_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5086457635, "lng": 127.0597319294, "distanceM": 3077, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Hyundai Department Store focuses on achieving customer satisfaction by exceeding expectations and reshaping the lifestyle culture to suit each individual's needs and wants. Connected to Samseong Station on Seoul Subway Line 2, Hyundai Department Store Trade Center is easily accessible and among the most sought-after shopping destinations in Seoul along with the nearby COEX Mall.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -712,10 +1144,18 @@ "title": "Starfield COEX Mall (스타필드 코엑스몰)", "address": "513 Yeongdong-daero, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/65/3081365_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5117148467, "lng": 127.0594429796, "distanceM": 3116, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Starfield COEX Mall, located at the center of Seoul, leads in trend and culture. Combining fashion, food, culture and entertainment, the mall provides everything the visitors need. The Starfield Library offers a space to rest and entertainment with books.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -725,10 +1165,18 @@ "title": "Parnas Mall (파르나스몰)", "address": "521, Teheran-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/56/2530456_image2_1.JPG", + "imageSource": "tourapi", "tel": null, "lat": 37.5095984514, "lng": 127.0608845757, "distanceM": 3194, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Parnas Mall is the first premium casual shopping mall opened by a hotel chain. Grand Intercontinental Seoul's Parnas Mall is located on the first underground level and features shopping, food, beverages, and cultural activities all in one place.", + "homepage": "http://www.parnasmall.com/", "rating": null, "reviewCount": null, "openingHours": null @@ -738,10 +1186,18 @@ "title": "Itaewon Shopping Street (이태원 쇼핑거리)", "address": "Itaewon-dong, Yongsan-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/09/2933409_image2_1.bmp", + "imageSource": "tourapi", "tel": null, "lat": 37.533861039, "lng": 126.9906791694, "distanceM": 4451, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Itaewon Shopping Street is a 1.4-kilometer-long road located near Itaewon Station. There is an enormous variety of shops, entertainment venues, and restaurants lined along both sides of the street. As the neighborhood has a reputation as a mini melting pot in Seoul where languages other than Korean are widely spoken, it is one of the most visited places by international visitors. It has become a gateway for many international visitors to receive services and information on basic tourist needs such as accommodations, shopping, tourist attractions, and more.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -751,10 +1207,18 @@ "title": "Seongsu Stage 35 (스테이지35 성수)", "address": "35 Yeonmujang-gil, Seongdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/37/3498037_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5431610875, "lng": 127.0534981848, "distanceM": 4918, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "Located in Seongsu-dong, a popular neighborhood in Seoul, Stage 35 is a cultural complex spread across four floors. Capturing the unique vibes of Seongsu-dong and keeping up with trends, Stage 35 hosts pop-up stores, art exhibitions, showcase launches, and offers a space for content filming. It is considered a must-visit place for visitors who want to keep up with trends and experience brands' new season items. It has hosted collaborations with popular brands, including Levi's, Comme des Garçons, Thom Browne, and Bao Bao.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -764,10 +1228,18 @@ "title": "Musinsa Standard Seongsu (무신사 스탠다드 성수)", "address": "83 Yeonmujang-gil, Seongdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/02/3413102_image2_1.png", + "imageSource": "tourapi", "tel": null, "lat": 37.5418224475, "lng": 127.0586866388, "distanceM": 5047, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "Located near Seongsu-dong Café Street, this is the physical store of the online editorial shop MUSINSA. The store offers affordable, high-quality clothing aimed at young adults in their 20s, with neutral colors and minimalist designs popular among Koreans. It’s also a favorite indoor date spot for couples, providing a quick overview of the latest fashion trends.", + "homepage": "https://www.instagram.com/musinsa_standard/", "rating": null, "reviewCount": null, "openingHours": null @@ -777,10 +1249,18 @@ "title": "Hello apM (헬로에이피엠)", "address": "253 Jangchungdan-ro, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/14/3462914_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5674741142, "lng": 127.0081710683, "distanceM": 7104, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Hello apM is located within the Dongdaemun shopping district and appeals to customers in their 10s and 20s for it's latest trending styles and low prices. It is crowded year-round with young people from all over the world. Bargaining has faded out over recent years with prices more often indicated.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -790,10 +1270,18 @@ "title": "Hwanghak-dong Flea Market (Dokkaebi Market / Manmul Market) (황학동 벼룩시장 (도깨비시장/만물시장))", "address": "11-7 Majang-ro 5-gil, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/45/151945_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5691713182, "lng": 127.0181228914, "distanceM": 7154, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Hwanghak-dong Flea Market was named after the way how merchants travel from one place to another all over the country, as if like fleas hopping around from one spot to another, to collect rare and valuable items. This market was once a haven of antiques and collectibles, but with the formation of old-fashioned art street in 1983 in Janganpyeong, many classic art shops had moved out, leaving only used item and general goods stores. Now, visitors can find stores selling antiques, used furniture, electronics, clocks, jewelry, musical instruments, camera, and machinery – pretty much anything one c", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -803,10 +1291,18 @@ "title": "Harmony Mart Myeong-dong Station Branch (하모니마트 명동역점)", "address": "58 , Myeongdong 10-gil, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/43/2707843_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5613410916, "lng": 126.9857538405, "distanceM": 7181, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Harmony Mart Myeongdong Station Branch is a discount supermarket specializing in Korean products popular with foreign tourists. It’s on the 1st basement floor of the Shinil Building annex, just a minute's walk from Exit 8 of Myeongdong Subway Station, Jungu, Seoul. Shop here for kimchi, seaweed, ginseng products, tea, ramen, handicrafts, daily necessities and souvenirs. English, Chinese, and Japanese are spoken, and payments can be made in yen and yuan. With purchases of KRW 50,000 or more, there’s free delivery to accomodations within a 5km radius.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -816,10 +1312,18 @@ "title": "Migliore - Myeongdong Branch (밀리오레 (명동점))", "address": "115 Toegye-ro, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/30/3468830_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5611022086, "lng": 126.984540069, "distanceM": 7212, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Migliore Shopping Mall, located in Myeong-dong, reopened in August 2024 after undergoing remodeling. It provides customers with easy access to its stores, as it is directly connected to the Myeongdong Subway Station (Seoul Subway Line 4). Myeong-dong is regarded as the shopping district for youth in their 20s. Throughout the area, signs are written in English, Chinese, and Japanese for foreign visitors. The first and the second floors function as a shopping mall, and from the 3 rd to the 17 th floor as a hotel, providing visitors with an opportunity to shop and stay under the same roof. The fi", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -829,10 +1333,18 @@ "title": "Doota Mall (두타몰)", "address": "275, Jangchungdan-ro, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/48/3525648_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5688767395, "lng": 127.0087681967, "distanceM": 7245, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Doota Mall is a must-visit shopping destination that represents Dongdaemun-the center of K-fashion and culture in Seoul. Doota offers a true one-stop shopping experience across fashion, beauty, lifestyle, and dining-from K-designers, sportswear, women and men's apparel to a wide variety of cafes and restaurents. Open until midnight, Doota welcomes intenational travelers with special gifts and exclusive benefits.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -842,10 +1354,18 @@ "title": "Pyounghwa (Pyeonghwa) Fashion Town (서울 평화시장)", "address": "274, Cheonggyecheon-ro, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/61/614361_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5694211079, "lng": 127.0080126943, "distanceM": 7318, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "The Pyounghwa Fashion Town market in Dongdaemun has been selling fashion clothing and accessories for over 50 years ever since the end of the Korean War. It was here that in 1953 North Korean refugees started selling clothes made from US army uniforms. Their market was then named Pyounghwa, which means peace, in the hope that no other wars would be fought on Korean soil. The Pyounghwa Fashion Town was therefore the beginning of the 30,000 stores that now make up Dongdaemun Fashion Town, which is seen as one of the global centers of the fashion industry. Spread over a large area, this historica", + "homepage": "http://www.pyounghwa.com", "rating": null, "reviewCount": null, "openingHours": null @@ -854,11 +1374,19 @@ "id": "273750", "title": "Shinsegae Department Store - Main Store (신세계백화점 (본점))", "address": "63 Sogong-ro, Jung-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/31/4020131_image2_1.jpg", + "imageSource": "naver", "tel": null, "lat": 37.5609271625, "lng": 126.9808542989, "distanceM": 7366, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Shinsegae Department Store opened its doors as the first modern department store in the country in 1960. It stands where Korea's first department store, the Japanese Misreukkosi Department Store, used to be in the 1930s. After undergoing remodeling in 2007, it reopened as a luxury hall, featuring diverse brands ranging from the top three international luxury brands to new designer brands. In addition, the Trinity Gardens and art halls in the department store serve as a cultural space for a shopping experience that combines art and shopping.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -868,10 +1396,18 @@ "title": "Seungjin Toy (승진완구)", "address": "30, Jong-ro 52-gil, Jongno-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/05/1309005_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5713154428, "lng": 127.0141843007, "distanceM": 7430, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Seungjin Toy is a toy store that carries almost every kind of toy imaginable from stuffed animals to character dolls and much more. What makes this store even more attractive to many customers is that their merchandise is, on average, 30% cheaper than that of their competitors.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -881,10 +1417,18 @@ "title": "Beauty Play (뷰티플레이)", "address": "73 Myeongdong-gil, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/25/3564025_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5643240879, "lng": 126.9863231484, "distanceM": 7448, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Beauty Play is a K-beauty experience center operated by the Korea Cosmetics Industry Institute and supported by the Ministry of Health and Welfare. It offers a wide variety of sample Korean beauty products for testing  as well as diverse beauty experience programs such as makeup touch-up service (choice of base, eyes, or lips), personal color test, and skin evaluation. Visitors can also ask for product recommendation based on their skin type or skincare concerns. Beauty Play also frequently hosts free one-day classes, which are announced online via its official website. It also hosts a va", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -894,10 +1438,18 @@ "title": "Dongdaemun Shopping Complex·Dongdaemun Shopping Town (동대문 종합시장·동대문 쇼핑타운)", "address": "266 Jong-ro, Jongno-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/49/710249_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5707292767, "lng": 127.0073293863, "distanceM": 7473, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Dongdaemun Shopping Complex is one of Korea’s most well-known markets. It was founded in December 1970 as the largest of its kind in Asia and has maintained that status for the last 40 years. Browsing the plethora of shops, you can find fabric and clothing following all the latest global fashion trends. Dongdaemun Shopping Complex continues to build up its reputation as a hub of international design.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -907,10 +1459,18 @@ "title": "Donga Stationery (동아완구)", "address": "5 Jong-ro 52-gil, Jongno-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/63/3357663_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5719181289, "lng": 127.0129788379, "distanceM": 7512, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Donga Stationery is a stationery store located along Changsin-dong Stationery Street. The stop offers a full range of stationery and character goods and is popular among children and adults alike. The shop is located right by Dongdaemun Station (Seoul Subway Line 1), Exit 4, making it easily accessible.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -920,10 +1480,18 @@ "title": "Seoul Folk Flea Market (서울 풍물시장)", "address": "21 Cheonho-daero 4-gil, Dongdaemun-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/63/3107663_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5727182604, "lng": 127.025466566, "distanceM": 7519, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "The Seoul Folk Flea Market is located around Cheonggyecheon Stream's Hwanghakgyo Bridge and Sinseol-dong Station and is on its way to becoming a famous tourist attraction along with the already famous Cheonggyeocheon Stream. The Seoul Folk Flea Market is one of the major folk flea markets preserving the culture of the traditional Korean marketplace and drawing in visitors with a range of folk items that embody the unique charm of Korea. Folk items include everyday items, souvenirs, traditional goods and even traditional foods, allowing visitors to enjoy shopping and eating all under the same r", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -932,11 +1500,19 @@ "id": "3110407", "title": "Junggok-dong Furniture Street (중곡동 가구거리)", "address": "Cheonho-daero, Gwangjin-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/11/3478411_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.5571404902, "lng": 127.0796620717, "distanceM": 7535, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "Junggok-dong Furniture Street stretches between Achasan Subway Station and Gunjagyo Bridge, hosting a concentration of furniture stores on either side of the main road. This area accommodates a diverse range of furniture stores, featuring well-known domestic and international brands alongside smaller and medium-sized furniture shops. It serves as a convenient destination for customers to compare and purchase various furniture items, including beds, sofas, dining tables, wardrobes, chairs, and interior accessories, all within close proximity. The accessibility to Gunja Subway Station makes it e", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -947,11 +1523,19 @@ "id": "782947", "title": "Best Western Premier Gangnam Hotel (베스트웨스턴 프리미어 강남호텔)", "address": "139, Bongeunsa-ro, Gangnam-gu, Seoul", - "image": null, + "image": "https://cdn.imweb.me/upload/S202003138afcbb5e0f71c/44ecb591793c5.png", + "imageSource": "homepage", "tel": null, "lat": 37.5063677122, "lng": 127.029790275, "distanceM": 418, + "travel": { + "mode": "walk", + "minutes": 5, + "label": "5 min walk" + }, + "overview": "Best Western Premier Gangnam Hotel offers double, twin and suite rooms in contemporary ambience and design. Multilingual staff members and a business center provide the best business atmosphere for visitors. The hotel is located in the heart of Gangnam, with easy access to COEX, Korea World Trade Center, Olympic Stadium, and a number of luxury department stores and the combined business and entertainment area of Gangnam.", + "homepage": "http://www.bestwesterngangnam.com/", "rating": null, "reviewCount": null, "openingHours": null @@ -961,10 +1545,18 @@ "title": "Imperial Palace Hotel (임피리얼 팰리스 호텔)", "address": "640 Eonju-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/63/2048263_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5136697521, "lng": 127.0358867353, "distanceM": 1340, + "travel": { + "mode": "walk", + "minutes": 17, + "label": "17 min walk" + }, + "overview": "Imperial Palace Hotel first opened on September 18, 1989, starting as a deluxe hotel and becoming a superior deluxe hotel after 10 years in June 1999. The hotel has remained the pride of the Korean hotel industry thanks to its effective management and improving domestic capital. In 2005, it carried out a large-scale remodeling project to enlarge its size to resemble luxurious European hotels, including a large-sized lobby, convention center that can accommodate over 1,000 visitors, classical wedding hall, and 405 guestrooms. The hotel is part of a chain, along with Imperial Palace Boutique Hot", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -974,10 +1566,18 @@ "title": "GyoDae GuestHouse (교대게스트하우스)", "address": "116 , Saimdang-ro 17-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/81/2529081_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4933329219, "lng": 127.0190443994, "distanceM": 1412, + "travel": { + "mode": "walk", + "minutes": 18, + "label": "18 min walk" + }, + "overview": "Gyodae Guesthouse is located in Seocho Samsung Raemian Apartments, near Gyodae station, Seoul. Residents share the space in a typical Korean home, with two separate rooms - each equipped with a computer and desk - plus shared kitchen, bathroom, and living room with TV and sofa, Foreign students studying at nearby universities often stay here for extended periods. A laundry service is provided free of charge.", + "homepage": "http://blog.naver.com/ysh230", "rating": null, "reviewCount": null, "openingHours": null @@ -987,10 +1587,18 @@ "title": "The Hyoosik Nouvelle Seoul Itaewon (더휴식 누베르 서울 이태원점)", "address": "11 Usadan-ro 14-gil, Yongsan-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/67/3483867_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5343166442, "lng": 126.9963480845, "distanceM": 4157, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "The Hyoosik Nouvelle Seoul Itaewon aims to rediscover Seoul through creativity and inspiration. The overall design of the hotel is inspired by French avant-garde, using a variety of objects and props to create an artistic and stylish atmosphere. The hotel has Collection T room type, a twin bedroom; Collection D room type, a double bedroom; and Collection S room type, a single bedroom. On the first floor of the hotel is a guest lobby and a pasta restaurant. The hotel's parking lot is limited in space, and therefore guests are advised to use a nearby public parking lot.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1002,10 +1610,18 @@ "title": "ab Cafe At Bali (에이비카페 At Bali)", "address": "32 Gangnam-daero 102-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/96/2947096_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5029569643, "lng": 127.0279516492, "distanceM": 318, + "travel": { + "mode": "walk", + "minutes": 4, + "label": "4 min walk" + }, + "overview": "A cafe where you can experience digital drawing It is a cafe with the concept of a vacation resort with an atmosphere that makes you feel like you are in a Southeast Asian resort. The upbeat atmosphere with rattan furniture placed here and there is always popular enough to be fully booked. The Wacom Lounge on the 3rd floor is a space where ‘Wacom One’, optimized for webtoon creation, is installed. Anyone can use it, and you can experience digital drawing, editing, and correction with the 'Wacom One' tablet.", + "homepage": "https://www.instagram.com/abcafe_gangnam/", "rating": null, "reviewCount": null, "openingHours": null @@ -1015,10 +1631,18 @@ "title": "Dojeong Yukgwan (도정육관)", "address": "42 Seocho-daero 78-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/28/3551128_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4940774451, "lng": 127.0282407632, "distanceM": 1236, + "travel": { + "mode": "walk", + "minutes": 15, + "label": "15 min walk" + }, + "overview": "Dojeong Yukgwan is a Korean BBQ restaurant in Gangnam. Every morning, fresh rice is milled on-site to cook the rice, and carefully aged meat is served alongside. The meat is aged at a consistent temperature and humidity, resulting in a tender texture and deep flavor. The meat is grilled over charcoal, with staff grilling the meat to serve it in optimal condition. A variety of side dishes are served alongside the food. The interior features warm lighting and wooden interiors, creating a relaxed yet sophisticated atmosphere.", + "homepage": "https://www.instagram.com/dojeong_seoul/", "rating": null, "reviewCount": null, "openingHours": null @@ -1028,10 +1652,18 @@ "title": "BBQ Yul (고깃집열)", "address": "48 Seocho-daero 78-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/22/3551922_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4935414029, "lng": 127.0286212989, "distanceM": 1301, + "travel": { + "mode": "walk", + "minutes": 16, + "label": "16 min walk" + }, + "overview": "BBQ Yul, a Korean barbecue restaurant in Gangnam, boasts deep flavors of pork aged for 336 hours and charcoal. All meats are sourced domestically and cooked by the skilled staff to ensure optimal cooking and flavor. The interior is composed of warm lighting and wooden decor, and opening the folding door reveals an open space like a terrace.", + "homepage": "https://www.instagram.com/bbqyul_official/", "rating": null, "reviewCount": null, "openingHours": null @@ -1040,11 +1672,19 @@ "id": "3333569", "title": "Yoojung Restaurant (유정식당)", "address": "14 Dosan-daero 28-gil, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/72/2834872_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.5184190599, "lng": 127.0280817557, "distanceM": 1510, + "travel": { + "mode": "walk", + "minutes": 19, + "label": "19 min walk" + }, + "overview": "Yoojung Restaurant is well-known, despite being located in a side-street, thanks to its having been frequented often by BTS members during their training days. BTS fans will love seeing the many pictures and posters of BTS decorating the walls, and can enjoy the same dishes loved by their idols. Some of the stars' most ordered dishes have had their names changed to reflect this.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1054,10 +1694,18 @@ "title": "Modern Nulang Central City Branch (모던눌랑 센트럴시티점)", "address": "205 Sapyeong-daero, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/85/3570685_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5045314196, "lng": 127.0077895512, "distanceM": 1568, + "travel": { + "mode": "walk", + "minutes": 20, + "label": "20 min walk" + }, + "overview": "Setting a romantic and modern atmosphere, Modern Nulang is a Chinese restaurant inspired by the \"New Woman\" concept from Shanghai's modern history. The restaurant’s design reflects Shanghai’s modern culture in the 1930s, portraying itself as a place that sets trends and is frequented by intelligent, sophisticated women. Decorative elements like a train platform, murals, and antique décor are scattered throughout the space, capturing the aesthetic essence of that era. Even the food served here stays true to the concept, presented in an elegant and romantic fashion. Signature ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1067,10 +1715,18 @@ "title": "Texas de Brazil Central City Branch (텍사스 데 브라질 센트럴시티점)", "address": "205 Sapyeong-daero, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/32/3570532_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5045314196, "lng": 127.0077895512, "distanceM": 1568, + "travel": { + "mode": "walk", + "minutes": 20, + "label": "20 min walk" + }, + "overview": "Located in Seocho-gu, Texas de Brazil Central City Branch offers 15 different types of churrasco—traditional Brazilian steak barbecue—and 50 varieties of Brazilian dishes. Churrasco refers to meat skewered on a 1.2-meter-long stick and grilled over hard charcoal, making it tender and juicy. The carver also comes to the guest’s table to slice—or \"carve\"—the meat portions according to the guest’s request. Not only is the food served here a treat for the palate, but for the eyes as well.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1079,11 +1735,19 @@ "id": "3392013", "title": "Cafe PLENO (카페쁠레노)", "address": "724, Seolleung-ro, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/14/2947414_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5193525139, "lng": 127.0408194587, "distanceM": 2102, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Actor Jang Keun-Suk This cafe is run by actor Jang Keun-Suk, who is called the 'Asian Prince'. The white-style interior and plant decorations create a refreshing atmosphere, making you feel as if you are visiting a botanical garden. The flower decoration of Cafe PLENO changes according to the season and consists of flowers that can be enjoyed in that season. It is considered a good place to enjoy a quiet leisure time with excellent lighting as well as coffee taste. The drinks and dessert decorations are also great. Many Japanese tourists come to see Jang Keun-Suk, and a Japanese menu is also p", + "homepage": "https://www.cafepleno.com/", "rating": null, "reviewCount": null, "openingHours": null @@ -1093,10 +1757,18 @@ "title": "Passi 0914 (파시0914)", "address": "15 Dosan-daero 45-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/66/2870066_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5232825107, "lng": 127.0351337538, "distanceM": 2207, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Passi 0914 is an Italian resturant serving pasta and ovenbrick-baked pizza near the entrance to Dosan Park. The restaurant only has three terrace tables so reservations are a must. The restaurant was featured as a filming site in the drama \"Celebrity (2023).\"", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1106,10 +1778,18 @@ "title": "Buvette Main Branch (부베트 본점)", "address": "854 Nonhyeon-ro, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/89/3570289_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5253738224, "lng": 127.0288814863, "distanceM": 2284, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Located in Gangnam, Buvette is a French Gastrotheque where one can enjoy stories and aesthetics of European-style antiques. The place offers heartwarming home-style meals that have been passed down through generations. Early morning coffee and breakfast, lunch with friends, dinner with family, and after-meal cocktails are all possible at Buvette, where delicious food and a lively atmosphere come together to suit a variety of lifestyles. It also has an outdoor terrace that sets the perfect atmosphere for a glass of wine or champagne and is particularly popular among the younger generation. Its ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1119,10 +1799,18 @@ "title": "mmn (미미네)", "address": "39, Dosan-daero 66-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/94/2945894_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5209912689, "lng": 127.0439663475, "distanceM": 2424, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Ive An Yujin and Jang Wonyoung’s brunch cafe This is the brunch cafe that Ive An Yujin and Jang Wonyoung stopped by after Pilates class in the entertainment program ‘An Omniscient Point of View’. It exudes a fresh yet exotic image with turquoise paint and an outdoor terrace. The menu is quite diverse, including salads, sandwiches, and salmon dishes. Among them, the most popular menu, onion soup, is served in a pottery cup and is fun to see. Carrot cake is also famous, so be sure to try it with coffee.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1131,11 +1819,19 @@ "id": "2442632", "title": "Ogane Jokbal (오가네족발)", "address": "21 Nonhyeon-ro 36-gil, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/46/2478046_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.4850954296, "lng": 127.0435674002, "distanceM": 2734, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Ogane Jokbal is known for its jokbal (braised pigs' feet) and bossam (kimchi cabbage wraps with pork). Jokbal (braised pigs' feet) refers to pigs’ legs braised for extended periods. The meat comes out of the braising process chewy and flavorful. Saeujeot (salted shrimp) is used as the sauce. Bossam (kimchi cabbage wraps with pork) and makguksu (buckwheat noodles) are also on the menu. Lunch specials include the bossam jeongsik (kimchi cabbage wraps with pork set menu) and naengmakguksu (cold buckwheat noodles). Ogane Jokbal was included in the MICHELIN Guide Seoul 2019.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1145,10 +1841,18 @@ "title": "Sichuan House (시추안하우스 본점)", "address": "29 Teheran-ro 87-gil, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/39/3574239_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.509642839, "lng": 127.0580070584, "distanceM": 2943, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Sichuan House serves over 30 Chinese dishes, featuring fiery chili peppers from Sichuan perfectly balanced with 17 spices from around the world. Since introducing authentic mala food for the first time in Korea in 2009, it offers dishes such as mala hot pot, Sichuan spicy fried chicken, and tan tan noodles. The interior, utilizing brown bricks and black frames, creates an atmosphere reminiscent of the streets of Shanghai.", + "homepage": "http://www.sichuanhouse.co.kr", "rating": null, "reviewCount": null, "openingHours": null @@ -1158,10 +1862,18 @@ "title": "Shinuiju Chapsal Sundae (신의주찹쌀순대)", "address": "725 Yeongdong-daero, Gangnam-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/47/2833047_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5225301805, "lng": 127.05517084, "distanceM": 3285, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "SHINee's Key and Minho's Soul Food It is a Sundae and Rice Soup restaurant that SHINee's Key and Minho have chosen as the soul food that they used to eat after their schedules since their trainee days. Rice Soup can be enjoyed white with only salted shrimp in the soup, or it is delicious with minced seasoning. The bowl will be empty in no time when eaten with Julienne Radish Fresh Salad to a plain soup without the smell of pork. The Stuffed Squid that Key ordered is also a delicacy.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1171,10 +1883,18 @@ "title": "Maison Hannam (메종 한남)", "address": "24 UN village 3-gil, Yongsan-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/58/3045758_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5343030538, "lng": 127.0129382404, "distanceM": 3439, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Remodeled from the prevoius Italian Embassy, this restaurant boasts an excellent view of the Hangang River and Lotte World Tower. It is a popular place for dates or birthday parties, requiring a reservation at least a month in advance to sit on the terrace with a view of the Hangang River. Among the recommended menus is the Maison Lunch Set, which offers three courses, including appetizers (such as grilled scallops), pasta, and Korean beef steak. The food is served warm, and the utensils are changed frequently for a pleasant meal. There is a glass greenhouse on the outdoor terrace, so guests c", + "homepage": "https://www.instagram.com/maisonhannam_official/", "rating": null, "reviewCount": null, "openingHours": null @@ -1183,11 +1903,19 @@ "id": "3107495", "title": "Kervan Turkish Restaurant (케르반레스토랑)", "address": "192 Itaewon-ro, Yongsan-gu, Seoul", - "image": null, + "image": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/1a/3a/3e/65/photo1jpg.jpg?w=1400&h=-1&s=1", + "imageSource": "naver", "tel": null, "lat": 37.5344166147, "lng": 126.9954037239, "distanceM": 4218, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Kervan is a Turkish restaurant located in Itaewon, offering authentic kebab, pidé, and Turkish desserts. It faithfully recreates the Turkish culture and food through its interior, decorated with traditional tiles, and dishes prepared by a chef from Türkiye. Main menus include Chicken steak, Rich pidé, and Chicken shish kebab.", + "homepage": "https://www.instagram.com/kervankorea/", "rating": null, "reviewCount": null, "openingHours": null @@ -1197,10 +1925,18 @@ "title": "Sigol Bossam (시골보쌈)", "address": "25 Bangbaecheon-ro 2-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/70/2684570_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.477125846, "lng": 126.9842285813, "distanceM": 4793, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "Potato Ongsim is also a popular dish. The best menu at this restaurant is kimchi cabbage wraps with pork. This Korean dishes restaurant is located in Seocho-gu, Seoul.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1210,10 +1946,18 @@ "title": "Ongeundal (옹근달)", "address": "41-1, Seongsui-ro 7-gil, Seongdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/61/2900861_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5427861223, "lng": 127.0530149062, "distanceM": 4861, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "This bakery in Seongsu-dong boasts a colorful and unique visual, and is gaining popularity for its “cruffin,” a hybrid of a croissant and muffin. The menu includes a variety of breads and desserts, such as canelé, pound cake, crumble, and mille-feuille, making it a paradise for bread-lovers. The courtyard of the building, which was remodeled from an old factory, has thick bushes and a small square pond, offering a unique view. The floor-to-ceiling windows in this two-story building create the feeling of a wide, open space, making it full of photo opportunities.", + "homepage": "https://www.instagram.com/onguendal", "rating": null, "reviewCount": null, "openingHours": null @@ -1223,10 +1967,18 @@ "title": "Daelim Changgo Gallery (성수동 대림창고 갤러리)", "address": "78 Seongsui-ro, Seongdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/63/2374863_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5420057167, "lng": 127.0563062954, "distanceM": 4943, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "Daelim Changgo Gallery, which is a landmark in Seongsu-dong, is a red-brick building that was once used as a rice mill in the 1970s. It is now a cafe and art gellery that preserves as much of the original rice mill atmosphere as possible so it exudes fascinatingly vintage vibes, widely loved by young couples.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1237,11 +1989,19 @@ "id": "1459282", "title": "Spa In New York (스파인뉴욕 (SPA IN NEWYORK))", "address": "406, Gangnam-daero, Gangnam-gu, Seoul", - "image": null, + "image": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/29/e1/2b/c3/spa-relaxation-room.jpg?w=600&h=600&s=1", + "imageSource": "naver", "tel": null, "lat": 37.4989324255, "lng": 127.0276129057, "distanceM": 699, + "travel": { + "mode": "walk", + "minutes": 9, + "label": "9 min walk" + }, + "overview": "Located in Seocho-dong, Seocho-gu, SPA IN NEW YORK is a spa and aesthetic center providing beauty know-how and relaxing spa treatments. The interior of the center, a combination of natural wood and stones, is designed to provide utmost comfort and pleasure to its visitors. The center’s representative spa treatment program, Marine Aqua Aroma Therapy, restores energy and balance to the exhausted body and mind using fresh marine therapy materials. Other popular programs include Power Detox Alga, which helps excrete toxins from the body, and Healing Back Stone Therapy, which is effective for relie", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1250,11 +2010,19 @@ "id": "1300249", "title": "JW Spa (제이더블유스파)", "address": "565, Nonhyeon-ro, Gangnam-gu, Seoul-si", - "image": null, + "image": "https://cache.marriott.com/content/dam/marriott-renditions/HKTKL/hktkl-suite-balcony-2974-hor-clsc.jpg?output-quality=70&interpolation=progressive-bilinear&downsize=1920px:*", + "imageSource": "naver", "tel": null, "lat": 37.5065205433, "lng": 127.0337426883, "distanceM": 759, + "travel": { + "mode": "walk", + "minutes": 9, + "label": "9 min walk" + }, + "overview": "Located in Yeoksam-dong, Gangnam-gu, JW. Spa 1ST tries hard to carry out the best spa through professional spa planners who help to find suitable spa treatment for individuals.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1264,10 +2032,18 @@ "title": "Spa Lei (스파레이)", "address": "5, Gangnam-daero 107-gil, Seocho-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/72/2024972_image2_1.jpg", + "imageSource": "tourapi", "tel": null, "lat": 37.5178689471, "lng": 127.0182354456, "distanceM": 1566, + "travel": { + "mode": "walk", + "minutes": 20, + "label": "20 min walk" + }, + "overview": "Situated in Seocho-gu Jamwon-dong, is an exclusive women-only jjimjilbang and sauna that presents a traditional eastern European atmosphere with high-class facilities and a variety of convenient amenities.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1276,11 +2052,19 @@ "id": "1295190", "title": "AMORE Spa (아모레퍼시픽 스파)", "address": "21, Apgujeong-ro 29-gil, Gangnam-gu, Seoul", - "image": null, + "image": "https://i.pinimg.com/736x/61/45/30/6145303d55dd2db805476aa1b14c9cf9.jpg", + "imageSource": "naver", "tel": null, "lat": 37.5286678625, "lng": 127.0276620598, "distanceM": 2637, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "AmorePacific, a Korean brand, initially gained popularity in New York since its opening of AMORE Beauty Gallery & Spa in Soho, New York. The AMORE Spa is a popular spa and treatment center frequented by many international celebrities. The AMORE Spa Seoul branch, opened in April 2005, offers approximately 30 different kinds of programs. One of the most popular spa programs is Spa Therapy, which uses a diverse range of natural therapy materials including lotus flower, ginger and bamboo. Another popular program is the Halla Green Tea program, which uses green tea leaves grown in Jeju's Hallasan M", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1289,11 +2073,19 @@ "id": "1300201", "title": "Q Spa & Clinic (큐스파앤클리닉)", "address": "8 Samseong-ro 133-gil, Gangnam-gu, Seoul-si", - "image": null, + "image": "https://dynamic-media-cdn.tripadvisor.com/media/photo-o/28/56/0d/cb/q-spa-clinic.jpg?w=600&h=600&s=1", + "imageSource": "naver", "tel": null, "lat": 37.5197470544, "lng": 127.0487215059, "distanceM": 2642, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Q Spa & Clinic has clinical and spa programs managed by expert staff certified in cosmetology and trained to handle the state-of-the-art equipment and facilities.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1302,11 +2094,19 @@ "id": "1024874", "title": "Will Spa (윌스파)", "address": "524, Bongeunsa-ro, Gangnam-gu, Seoul", - "image": null, + "image": "https://dimg04.tripcdn.com/images/0M70l12000sgvefyuC48E.jpg", + "imageSource": "naver", "tel": null, "lat": 37.512928552, "lng": 127.0570876042, "distanceM": 2950, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Willspa operates 24 hours in the Gangnam area, featuring luxurious spa that is equipped with suitable size, facility, and programs for foreign visitors’ taste.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1315,11 +2115,19 @@ "id": "669211", "title": "Riverside Spa Land (강변스파랜드)", "address": "2nd basement level, 45, Guuigangbyeon-ro, Gwangjin-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/98/3401698_image2_1.JPG", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.5348266305, "lng": 127.0916116181, "distanceM": 6753, + "travel": { + "mode": "drive", + "minutes": 8, + "label": "8 min by car" + }, + "overview": "Riverside Spa Land opened in 1988. It contains a Korean-style sauna (jjimjilbang), restaurant, and a large game center. The spa facilities utilize underground mineral water rich in sulfur, which is said to be effective toward atopy and other skin disorders. Because it is located at the heart of Seoul, it is very accessible, and Riverside Spa Land’s wide range of facilities and services make it a popular destination for many.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null @@ -1332,389 +2140,629 @@ "title": "Gugak Performance Jinyeon (국악공연 진연)", "address": "10 Insadong 5-gil, Jongno-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/35/4060435_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-2-953-0515", "lat": 37.5728652641047, "lng": 126.985653181823, "distanceM": 8323, + "travel": { + "mode": "drive", + "minutes": 10, + "label": "10 min by car" + }, + "overview": "The gugak performance “Jinyeon, The Music of the Royal Banquet” offers a unique opportunity to experience the diversity of traditional Korean arts on a single stage. Set in an intimate venue designed in the style of a traditional Korean house, it allows for close interaction between the audience and performers. The program features a wide range of music performed on traditional instruments, spanning Korean music, K-pop, classical pieces, and world folk songs. As an all-in-one performance, it brings together elements of Korean culture, sound, instruments, and live performance into a single imme", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260101", "endDate": "20261231", - "distanceKm": 8.3 + "distanceKm": 8.3, + "month": 1, + "season": "winter" }, { "id": "3113698", "title": "APAP Artwork Tour (APAP 작품투어 (안양공공예술프로젝트))", "address": "180 Yesulgongwon-ro, Manan-gu, Anyang-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/69/4054469_image2_1.jpg", + "imageSource": "tourapi", "tel": "Anyang Papillon: +82-31-687-0548", "lat": 37.41945269174406, "lng": 126.92561681569023, "distanceM": 12963, + "travel": { + "mode": "drive", + "minutes": 16, + "label": "16 min by car" + }, + "overview": "The Anyang Public Art Project (APAP) started in 2005 and has led to the creation of many beautiful works of art that decorate the city's public spaces. The Anyang Foundation for Culture & Arts has created a tour program to explore the wonderful works, starting from the earliest works in 2005 up until now.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260310", "endDate": "20261130", - "distanceKm": 13.0 + "distanceKm": 13.0, + "month": 3, + "season": "spring" }, { "id": "4070501", "title": "Ssokssokdeul-i Festival (국립극장 쏙쏙들이페스티벌)", "address": "16 Heyri-ro, Tanhyeon-myeon, Paju-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/99/4104199_image2_1.jpeg", + "imageSource": "tourapi", "tel": "+82-31-870-9110", "lat": 37.7832839326, "lng": 126.6946859929, "distanceM": 42492, + "travel": { + "mode": "drive", + "minutes": 51, + "label": "51 min by car" + }, + "overview": "Ssokssokdeul-i Festival is a program organized by the National Theater of Korea’s Stage Arts Support Center, designed to make performing arts more accessible in everyday life. Held regularly throughout the year, it offers a variety of performances free of charge, creating greater opportunities for the public to engage with the arts in a relaxed and approachable setting. The festival takes place at the “Ssok” Experience Theater within the Stage Arts Support Center and features dynamic stages that can be enjoyed by audiences of all ages. Tickets for the performances are distributed on a first-co", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260314", "endDate": "20261226", - "distanceKm": 42.5 + "distanceKm": 42.5, + "month": 3, + "season": "spring" }, { "id": "3435521", "title": "Gombaengi Teotta (곰뱅이텄다)", "address": "경기도 안성시 보개면 남사당로 198-2", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/32/4039532_image2_1.jpg", + "imageSource": "tourapi-kor", "tel": null, "lat": 37.031777162443376, "lng": 127.31006979658326, "distanceM": 58336, + "travel": { + "mode": "drive", + "minutes": 70, + "label": "70 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260404", "endDate": "20261129", - "distanceKm": 58.3 + "distanceKm": 58.3, + "month": 4, + "season": "spring" }, { "id": "4108059", "title": "COSMOS BIGBANG 20TH ANNIVERSARY MEDIA EXHIBITION", "address": "B127 Seosomun-ro, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/94/4106894_image2_1.jpg", + "imageSource": "tourapi", "tel": "02-517-6017", "lat": 37.5635793508, "lng": 126.9753893632, "distanceM": 7869, + "travel": { + "mode": "drive", + "minutes": 9, + "label": "9 min by car" + }, + "overview": "The COSMOS BIGBANG 20TH ANNIVERSARY MEDIA EXHIBITION is an exhibition that celebrates the 20th anniversary of the group BIGBANG’s debut by presenting their music and activities over the past 20 years through media art. With “COSMOS” as its theme, the exhibition uses content tailored to each space to embody the connections and continuity linking the past, present, and future. It is being held at Dududo Seoul, an underground space located between Seoul Station and Euljiro 1(il)-ga Station, and visitors enter sequentially according to their pre-booked time slots. The exhibition space consists of ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260824", "endDate": "20260927", - "distanceKm": 7.9 + "distanceKm": 7.9, + "month": 8, + "season": "summer" }, { "id": "3514846", "title": "Seoul International Writers' Festival (서울국제작가축제)", "address": "26 Insadong 9-gil, Jongno-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/69/4073769_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-70-8826-5207", "lat": 37.5734199329, "lng": 126.9836265705, "distanceM": 8455, + "travel": { + "mode": "drive", + "minutes": 10, + "label": "10 min by car" + }, + "overview": "Seoul International Writers' Festival was founded in 2006 with aims to lay a foundation for connecting Korean literature and international literature. The festival provides the opportunity to get a deeper understanding of literature through programs such as meeting Korean and international authors and participating in writers' workshop.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260911", "endDate": "20260916", - "distanceKm": 8.5 + "distanceKm": 8.5, + "month": 9, + "season": "autumn" }, { "id": "4104955", "title": "Seoul Architecture Festival (서울건축문화제)", "address": "119 Sejong-daero, Jung-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/75/4103175_image2_1.png", + "imageSource": "tourapi", "tel": "070-7178-5840", "lat": 37.5668837502, "lng": 126.9767024196, "distanceM": 8113, + "travel": { + "mode": "drive", + "minutes": 10, + "label": "10 min by car" + }, + "overview": "The Architecture Festival aims to rediscover the unique architectural and urban charms of Seoul together with its citizens. Seoul generates creative potential based on “complex density”—a fusion of history, culture, and regional identity characteristic of a high-density city. Furthermore, amid rapid social change, the city has continuously adapted through “accelerated evolution,” which involves rapidly renewing its form based on its accumulated heritage. Moreover, through “glocality”—the intersection of local context and global trends—Seoul is expanding the unique urban experiences and values ", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260915", "endDate": "20261011", - "distanceKm": 8.1 + "distanceKm": 8.1, + "month": 9, + "season": "autumn" }, { "id": "293144", "title": "Bucheon International Comics Festival (부천국제만화축제)", "address": "1, Gilju-ro, Wonmi-gu, Bucheon-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/75/3557475_image2_1.JPG", + "imageSource": "tourapi", "tel": "+82-32-310-3071", "lat": 37.5081987483, "lng": 126.7421932715, "distanceM": 24986, + "travel": { + "mode": "drive", + "minutes": 30, + "label": "30 min by car" + }, + "overview": "Celebrating its 29th edition in 2026, the Bucheon International Comics Festival (BICOF) is one of Korea’s leading cultural tourism festivals devoted to comics and webtoons, offering something for everyone who loves the medium. This year’s festival, held under the theme “Comics & Webtoons: Easy to Love, Endless to Enjoy,” features a wide range of comic-related programs and cultural experiences designed to make the event more engaging and enjoyable for visitors. Highlights include curated and special exhibitions, meet-the-artist sessions for comics fans, the BICOF Playground and outdoor market b", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260918", "endDate": "20260920", - "distanceKm": 25.0 + "distanceKm": 25.0, + "month": 9, + "season": "autumn" }, { "id": "1391047", "title": "Gyeonggi Ceramics Biennale (경기도자비엔날레)", "address": "263 Gyeongchung-daero 2697beon-gil, Icheon-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/71/4065571_image2_1.jpg", + "imageSource": "tourapi", "tel": "+31-631-6501", "lat": 37.2769208162, "lng": 127.4237253326, "distanceM": 43374, + "travel": { + "mode": "drive", + "minutes": 52, + "label": "52 min by car" + }, + "overview": "The Gyeonggi Ceramics Biennale features a range of exhibitions and educational events. The event takes place at various locations in Korea famous for ceramics, including Icheon, Yeoju, and Gwangju.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260918", "endDate": "20261101", - "distanceKm": 43.4 + "distanceKm": 43.4, + "month": 9, + "season": "autumn" }, { "id": "2481976", "title": "Siheung Gaetgol Festival (시흥갯골축제)", "address": "287, Dongseo-ro, Siheung-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/09/3528809_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-31-310-2916, 19~20", "lat": 37.3897711469, "lng": 126.7812405855, "distanceM": 25075, + "travel": { + "mode": "drive", + "minutes": 30, + "label": "30 min by car" + }, + "overview": "The Siheung Gaetgol Festival is an eco-festival held at Siheung Gaetgol Eco Park, the only inland tidal creek in Gyeonggi-do. Surrounded by wetlands and former salt fields, the festival offers a variety of ways to relax, learn, and have fun in nature. To help protect the park’s natural environment, it is held as a car-free event. A signature program is the salt-pan performance, \"Memories of Salt, Dance of Water.\" Other performances include Concert in Gaetgol, Salt Warehouse Puppet Theater, Forest Music Festival, and the Gaetgol Senior Runway. Visitors can also enjoy a wide range of activities,", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260918", "endDate": "20260920", - "distanceKm": 25.1 + "distanceKm": 25.1, + "month": 9, + "season": "autumn" }, { "id": "3364856", "title": "Han River Walk (한강수계 걷기행사)", "address": "174-3 Daegok-ri, Gapyeong-eup, Gapyeong-gun, Gyeonggi-do", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/96/4105196_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-2-458-3315", "lat": 37.823886379, "lng": 127.5134174634, "distanceM": 55700, + "travel": { + "mode": "drive", + "minutes": 67, + "label": "67 min by car" + }, + "overview": "The Han River Walk is a walking event that takes place at various locations along the Hangang River. Participants can expect to enjoy light exercise in beautiful natural settings, as well as earn a completion medal. In addition to walking, the festival dates will feature a range of additional events for a lively environment.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260919", "endDate": "20261107", - "distanceKm": 55.7 + "distanceKm": 55.7, + "month": 9, + "season": "autumn" }, { "id": "715355", "title": "Seoul Street Arts Festival (서울거리예술축제)", "address": "10 Neungdong-ro, Gwangjin-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/56/4103256_image2_1.png", + "imageSource": "tourapi", "tel": "+82-2-2088-4957", "lat": 37.5317034539, "lng": 127.0667659257, "distanceM": 4704, + "travel": { + "mode": "drive", + "minutes": 6, + "label": "6 min by car" + }, + "overview": "Seoul Street Arts Festival is held in Ttukseom Hangang Park and Seoul Forest. This year's festival presents international performances from France, Lithuania, Chile and more, in addition to local performances.", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260919", "endDate": "20260920", - "distanceKm": 4.7 + "distanceKm": 4.7, + "month": 9, + "season": "autumn" }, { "id": "4083822", "title": "Suwon Hwaseong Media Art (수원화성 미디어아트)", "address": "Jangan-dong, Paldal-gu, Suwon-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/46/4076246_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-31-290-3622", "lat": 37.285512, "lng": 127.009673, "distanceM": 24444, + "travel": { + "mode": "drive", + "minutes": 29, + "label": "29 min by car" + }, + "overview": "Suwon Hwaseong Media Art is a nighttime festival held against the backdrop of Suwon Hwaseong Fortress, a UNESCO World Heritage Site. Since its launch in 2021, the event has presented large-scale media art inspired by the fortress and its history. Beginning in 2026, the festival has been newly reimagined under the theme “Saebit Dongrak: Suwon Hwaseong Blossoming in Light,” inviting visitors to experience the site through light and shared enjoyment. The festival brings together light, video, and performance to create immersive media art installations that trace the stories of people from the con", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20260919", "endDate": "20261006", - "distanceKm": 24.4 + "distanceKm": 24.4, + "month": 9, + "season": "autumn" }, { "id": "697439", "title": "Anseong Namsadang Baudeogi Festival (안성맞춤 남사당 바우덕이축제)", "address": "198, Namsadang-ro, Bogae-myeon, Anseong-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/93/4091593_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-31-678-5414", "lat": 37.0336344681, "lng": 127.3054103868, "distanceM": 57973, + "travel": { + "mode": "drive", + "minutes": 70, + "label": "70 min by car" + }, + "overview": "The Anseong Namsadang Baudeogi Festival is centered on Namsadang Nori, which is inscribed on UNESCO’s Representative List of the Intangible Cultural Heritage of Humanity. It preserves and builds on the artistic legacy of Baudeogi, the first female kkokdusoe (troupe leader) of the Joseon era, and the vibrant traditions of Anseong’s Namsadang troupe. The festival offers a rich mix of programs for all ages, from traditional cultural experiences and performances by Korean and international artists to folk performances from around the world. Visitors can also explore the Anseong Old Market, which r", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261002", "endDate": "20261005", - "distanceKm": 58.0 + "distanceKm": 58.0, + "month": 10, + "season": "autumn" }, { "id": "3379755", "title": "Bongsan Mask Dance(봉산탈춤 다 모여라~ )", "address": "서울특별시 종로구 종로1길 45 (세종로)", - "image": null, + "image": "https://korean.visitkorea.or.kr/kperformance/resource/8fbbd377-3903-4ad2-b368-fcf3329a82bd", + "imageSource": "naver", "tel": null, "lat": 37.574618321885374, "lng": 126.97838493180903, "distanceM": 8784, + "travel": { + "mode": "drive", + "minutes": 11, + "label": "11 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261002", "endDate": "20261004", - "distanceKm": 8.8 + "distanceKm": 8.8, + "month": 10, + "season": "autumn" }, { "id": "1273884", "title": "Bupyeong Pungmul Festival (부평풍물대축제)", "address": "34-1, Bupyeong-daero, Bupyeong-gu, Incheon", "image": "https://tong.visitkorea.or.kr/cms/resource/77/4067377_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-32-509-7516", "lat": 37.4944181127, "lng": 126.7229954336, "distanceM": 26705, + "travel": { + "mode": "drive", + "minutes": 32, + "label": "32 min by car" + }, + "overview": "Celebrating its 30th edition, the Bupyeong Pungmul Festival brings rhythm, excitement, and community spirit to the heart of the city. Since its launch in 1997, the festival has grown into one of Korea’s leading traditional cultural and performing arts festivals. For nearly three decades, it has filled the urban landscape with the vibrant sounds of Korean pungmul, creating a dynamic space where citizens and artists come together. At the heart of the festival are the pungmul troupes from Bupyeong’s 22 neighborhoods, whose lively rhythms have long served as a powerful force for community unity. H", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261002", "endDate": "20261004", - "distanceKm": 26.7 + "distanceKm": 26.7, + "month": 10, + "season": "autumn" }, { "id": "701688", "title": "Soraepogu Festival (소래포구 축제)", "address": "86-17 Jangdong-ro, Namdong-gu, Incheon", "image": "https://tong.visitkorea.or.kr/cms/resource/93/4074893_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-70-8820-4038", "lat": 37.3979276988, "lng": 126.7393126807, "distanceM": 27921, + "travel": { + "mode": "drive", + "minutes": 34, + "label": "34 min by car" + }, + "overview": "The Soraepogu Festival is a representative festival that embodies the region's identity, based on the rich ecological resources and historical and cultural value of Sorae Port. The festival grounds are composed of various themed zones, showcasing diverse programs that everyone, regardless of age, can enjoy. Ecological programs that allow visitors to directly experience Sorae's natural environment are offered. Additionally, resident participation programs are operated, created collaboratively by local residents, merchants, artists, and related organizations. Furthermore, the festival provides a", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261002", "endDate": "20261004", - "distanceKm": 27.9 + "distanceKm": 27.9, + "month": 10, + "season": "autumn" }, { "id": "3345888", "title": "Gangnam Festival (강남페스티벌)", "address": "320 Dosan-daero, Gangnam-gu, Seoul", - "image": null, + "image": "https://tong.visitkorea.or.kr/cms/resource/38/4101838_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-2-3423-5543", "lat": 37.5221428648, "lng": 127.0369343307, "distanceM": 2162, + "travel": { + "mode": "drive", + "minutes": 5, + "label": "5 min by car" + }, + "overview": "Gangnam Festival, the largest urban festival unfolding across the entire city center, begins with a spectacular street parade to mark the opening. The festival transforms the entirety of Gangnam into one massive festival space featuring K-POP concerts, family concerts for the whole family to enjoy, a Fashion & Beauty Festa combining K-fashion and performance, and a Beer & Food Festa offering diverse culinary experiences. As a global K-Culture festival combining the city's energy with Hallyu content, the Gangnam Festival is a representative cultural tourism event that promotes the charms of Gan", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261003", "endDate": "20261005", - "distanceKm": 2.2 + "distanceKm": 2.2, + "month": 10, + "season": "autumn" }, { "id": "4100813", "title": "Gumcheon Siheung Haenggung Cultural Festival (금천시흥행궁문화제)", "address": "44 Eunhaengnamu-ro, Geumcheon-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/02/4100002_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-70-4114-6352", "lat": 37.4506976783, "lng": 126.9074454056, "distanceM": 12034, + "travel": { + "mode": "drive", + "minutes": 14, + "label": "14 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261004", "endDate": "20261004", - "distanceKm": 12.0 + "distanceKm": 12.0, + "month": 10, + "season": "autumn" }, { "id": "4039267", "title": "King Jeongjo's Royal Parade (정조대왕 능행차 공동재현)", "address": "161 Sajik-ro, Jongno-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/59/4078459_image2_1.png", + "imageSource": "tourapi", "tel": "Seoul +82-786-0610Suwon +82-31-5191-2367 Hwaseong +82-70-4202-1017", "lat": 37.5760307, "lng": 126.9767218661, "distanceM": 8992, + "travel": { + "mode": "drive", + "minutes": 11, + "label": "11 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261004", "endDate": "20261004", - "distanceKm": 9.0 + "distanceKm": 9.0, + "month": 10, + "season": "autumn" }, { "id": "978249", "title": "Suwon Hwaseong Festival (수원화성문화제)", "address": "825, Jeongjo-ro, Paldal-gu, Suwon-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/90/4060890_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-31-5191-3647", "lat": 37.2818820192, "lng": 127.0143944638, "distanceM": 24827, + "travel": { + "mode": "drive", + "minutes": 30, + "label": "30 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261004", "endDate": "20261011", - "distanceKm": 24.8 + "distanceKm": 24.8, + "month": 10, + "season": "autumn" }, { "id": "4092329", "title": "GHOST Festival (Gyeonggi Hallyu OST Festival) (GHOST(경기 한류 OST) 페스티벌)", "address": "148-40 Imjingak-ro, Munsan-eup, Paju-si, Gyeonggi-do", "image": "https://tong.visitkorea.or.kr/cms/resource/98/4087098_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-70-7733-0390", "lat": 37.8920434573, "lng": 126.7447928585, "distanceM": 49618, + "travel": { + "mode": "drive", + "minutes": 60, + "label": "60 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261009", "endDate": "20261011", - "distanceKm": 49.6 + "distanceKm": 49.6, + "month": 10, + "season": "autumn" }, { "id": "4088698", "title": "Gangdong Prehistoric Culture Festival (강동선사문화축제)", "address": "875, Olympic-ro, Gangdong-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/77/3541977_image2_1.jpg", + "imageSource": "tourapi", "tel": "+82-2-3425-5240", "lat": 37.5590614348, "lng": 127.1306006547, "distanceM": 11054, + "travel": { + "mode": "drive", + "minutes": 13, + "label": "13 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261016", "endDate": "20261018", - "distanceKm": 11.1 + "distanceKm": 11.1, + "month": 10, + "season": "autumn" }, { "id": "4104871", "title": "Geumcheon Harmony Festival (금천하모니축제)", "address": "70 Siheung-daero 73-gil, Geumcheon-gu, Seoul", "image": "https://tong.visitkorea.or.kr/cms/resource/92/3483192_image2_1.jpg", + "imageSource": "tourapi", "tel": "070-4118-3420", "lat": 37.457065652, "lng": 126.8960368503, "distanceM": 12599, + "travel": { + "mode": "drive", + "minutes": 15, + "label": "15 min by car" + }, + "overview": "", + "homepage": "", "rating": null, "reviewCount": null, "openingHours": null, "startDate": "20261017", "endDate": "20261018", - "distanceKm": 12.6 + "distanceKm": 12.6, + "month": 10, + "season": "autumn" } ], "meta": { "source": "한국관광공사 TourAPI EngService2", - "fetchedAt": "2026-09-09T11:42:20", + "fetchedAt": "2026-09-09T13:50:13", "origin": { "lat": 37.5049823, "lng": 127.0254182, @@ -1793,5 +2841,12 @@ "영문 축제는 areacode 필드가 비어 있어 좌표 거리로 걸렀다.", "수술 전후 식이 적합성은 병원이 입력한 가이드로만 표시한다. 이 파일에는 없다." ] + }, + "filters": { + "total": 101, + "walk5": 2, + "walk15": 11, + "walkAll": 25, + "drive": 76 } } \ No newline at end of file diff --git a/supporters/src/layouts/Base.astro b/supporters/src/layouts/Base.astro index 5f9658f..51072bd 100644 --- a/supporters/src/layouts/Base.astro +++ b/supporters/src/layouts/Base.astro @@ -20,6 +20,22 @@ const isEn = lang === 'en'; const T = isEn ? { nav: [['/posts', 'Questions'], ['/videos', 'Doctors'], ['/newsroom', 'Newsroom'], ['/en/stay', 'Your Stay'], ['/about', 'About']], cta: 'Book a Consultation', supporters: 'SUPPORTERS', back: 'Back', top: 'Back to top', sample: 'This is a sample site, not yet public.' } : { nav: [['/posts', '상담 전 질문'], ['/videos', '의료진 영상'], ['/newsroom', '뉴스룸'], ['/visit', '방문 안내'], ['/about', '매체 소개']], cta: '상담 예약', supporters: '서포터즈', back: '이전 페이지', top: '맨 위로', sample: '샘플 사이트입니다. 정식 공개 전입니다.' }; + +// 언어 전환. 같은 내용의 짝이 있는 페이지만 서로 잇고, 없으면 그 언어의 입구로 보낸다. +// 영문 페이지가 늘어나면 이 표에 줄만 추가한다. +const PAIRS: Record = { '/visit': '/en/stay' }; +const KO_ENTRY = '/'; +const EN_ENTRY = '/en/stay'; +const path = (Astro.url.pathname.replace(/\.html$/, '').replace(/\/index$/, '/').replace(/\/$/, '') || '/'); +const koPair = Object.entries(PAIRS).find(([, en]) => en === path)?.[0]; +const otherHref = isEn ? (koPair ?? KO_ENTRY) : (PAIRS[path] ?? EN_ENTRY); +// 짝이 없으면 같은 글의 번역본으로 가는 것이 아니므로 그렇게 말한다. +const otherExact = isEn ? Boolean(koPair) : Boolean(PAIRS[path]); +// 영문 페이지의 예약 버튼은 병원의 외국인용 영문 사이트로 보낸다(factSheet.urlEn). +// 한국어 예약 페이지로 보내면 영어로 온 사람이 한국어 화면을 만난다. +const ctaHref = isEn + ? ((f as Record).reservationUrlEn || (f as Record).urlEn || reservationUrl || '/en/stay') + : (reservationUrl || '/visit'); // 의료광고 고지는 규정 대상이라 임의로 번역하지 않는다(의료법 56조·추천보증 심사지침). // 병원이 영문 문구를 확정해 site.json 의 sponsorNoticeEn / factSheet 의 sideEffectNoticeEn 에 넣기 전까지는 // 한국어 원문을 그대로 싣고 확인 대기임을 밝힌다. @@ -66,7 +82,12 @@ document.addEventListener('click',function(e){var a=e.target.closest&&e.target.c - {T.cta} +
+ KO + EN +
+ {T.cta} diff --git a/supporters/src/pages/en/stay.astro b/supporters/src/pages/en/stay.astro index 1601686..cf76b89 100644 --- a/supporters/src/pages/en/stay.astro +++ b/supporters/src/pages/en/stay.astro @@ -1,12 +1,19 @@ --- -// 외국인 환자용 체류 안내. 병원 좌표를 중심으로 숙박·식사·회복·관광·행사를 이동 반경 순으로 놓는다. -// 데이터는 한국관광공사 TourAPI 영문(EngService2)에서 scripts/fetch_medical_tourism.py 가 미리 수집한 -// src/data/medicalTourism.json 이다. 값을 만들지 않는다. -// - 평점·리뷰·영업시간은 TourAPI 가 주지 않아 싣지 않는다. -// - 수술 전후 식이 적합성은 의학 판단이라 병원이 확정한 문구만 싣는다(site.json dietGuideEn). -// - 회복 단계가 며칠째인지도 병원 확정값이다(site.json recoveryStagesEn). 단계는 이동 거리로만 정의한다. +// 외국인 환자용 체류 안내. 세 부분이다. +// 1. Around the clinic — 도보·차 소요 시간으로 거른 주변 장소 +// 2. Festivals — 계절로 묶은 행사 +// 3. Suggested days — 시간표와 지도가 붙은 동선 +// +// 데이터는 한국관광공사 TourAPI 영문(EngService2)에서 scripts/fetch_medical_tourism.py 가 +// 미리 수집한 src/data/medicalTourism.json 이다. 설명문은 detailCommon2 의 overview 다. +// +// 만들지 않는 것 +// - 평점·리뷰·영업시간: TourAPI 미제공. 싣지 않는다. +// - 링크: 공식 홈페이지가 있을 때만 걸고, 없으면 검색으로 보낸다. 주소를 지어내지 않는다. +// - 식이 적합성·회복 일수: 의학 판단이라 병원 확정값만 쓴다. +// - 일정의 시각: 진료 종료 시각을 가정으로 못박아 화면에 밝힌다. 병원 일정이 아니다. import Base from '../../layouts/Base.astro'; -import { fact, site as S, SITE_NAME, clinicSchema, reservationUrl, has } from '../../lib'; +import { fact, site as S, SITE_NAME, clinicSchema, has } from '../../lib'; import data from '../../data/medicalTourism.json'; const f = fact as Record; @@ -15,21 +22,110 @@ const clinic = f.shortNameEn || f.nameEn || f.shortName || 'the clinic'; const site = Astro.site!.toString().replace(/\/$/, ''); const T = data as any; -const GROUPS: Array<{ key: string; label: string; blurb: string }> = [ - { key: 'stay', label: 'Where to stay', blurb: 'Hotels and guesthouses near the clinic, for the days when visits are frequent.' }, - { key: 'restaurant', label: 'Where to eat', blurb: 'Restaurants within walking or short-ride distance.' }, - { key: 'wellness', label: 'Rest and recovery', blurb: 'Spas and jjimjilbang listed by the Korea Tourism Organization.' }, - { key: 'attraction', label: 'Places to see', blurb: 'Sights within the city, once you are able to travel further.' }, - { key: 'culture', label: 'Culture', blurb: 'Museums, theatres and halls.' }, - { key: 'shopping', label: 'Shopping', blurb: 'Department stores, markets and streets.' }, +type Place = { + id: string; title: string; address: string; image: string | null; overview: string; + homepage: string; lat: number | null; lng: number | null; distanceM: number | null; + travel: { mode: string; minutes: number; label: string } | null; +}; + +const GROUPS: Array<{ key: string; label: string; note: string }> = [ + { key: 'restaurant', label: 'Food', note: 'Restaurants and cafés' }, + { key: 'stay', label: 'Hotels', note: 'Places to sleep' }, + { key: 'wellness', label: 'Rest', note: 'Spas and jjimjilbang' }, + { key: 'attraction', label: 'Sights', note: 'Streets, parks, landmarks' }, + { key: 'culture', label: 'Culture', note: 'Museums, theatres, halls' }, + { key: 'shopping', label: 'Shopping', note: 'Stores and markets' }, ]; -const dist = (m: number | null) => (m === null ? '' : m < 1000 ? `${m} m` : `${(m / 1000).toFixed(1)} km`); -const dt = (d: string | null) => (d && d.length === 8 ? `${d.slice(0, 4)}.${d.slice(4, 6)}.${d.slice(6, 8)}` : ''); +const SEASONS = [ + { key: 'spring', label: 'Spring' }, { key: 'summer', label: 'Summer' }, + { key: 'autumn', label: 'Autumn' }, { key: 'winter', label: 'Winter' }, +]; +const MONTHS = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +const nowSeason = ['winter', 'winter', 'spring', 'spring', 'spring', 'summer', 'summer', 'summer', 'autumn', 'autumn', 'autumn', 'winter'][new Date().getMonth()]; -// 병원이 확정하기 전에는 비운다. 임의로 채우지 않는다. -const dietGuide: string = Sx.dietGuideEn || ''; -const recoveryStages: string = Sx.recoveryStagesEn || ''; +// 검색으로 보낸다. 없는 URL 을 만들지 않는다. +const searchUrl = (q: string) => `https://www.google.com/search?q=${encodeURIComponent(q + ' Seoul')}`; +// 칩은 누적 임계값으로 거른다. 카드에 이동수단과 도보 분을 실어 두면 스크립트가 판단한다. +const dt = (d: string | null) => (d && d.length === 8 ? `${MONTHS[+d.slice(4, 6)]} ${+d.slice(6, 8)}` : ''); +// 사진이 없을 때 이름을 대신 넣는다. 빈 회색칸보다 낫고, 없는 사진을 지어내지도 않는다. +const shortName = (t: string) => { + const m = t.match(/\(([^)]+)\)\s*$/); + return (m ? m[1] : t).replace(/\s*\[.*\]\s*/g, '').trim(); +}; +const firstSentence = (s: string, n = 150) => { + if (!s) return ''; + const cut = s.slice(0, n); + const stop = cut.lastIndexOf('. '); + return (stop > 60 ? cut.slice(0, stop + 1) : cut) + (s.length > n ? '…' : ''); +}; + +/* ── 동선. 실제 데이터에서 만들고, 시각은 가정임을 화면에 밝힌다. ── */ +const oLat = T.meta.origin.lat, oLng = T.meta.origin.lng; +const pick = (key: string, maxMin: number, n: number): Place[] => + ((T.places[key] ?? []) as Place[]) + .filter((p) => p.travel && p.travel.mode === 'walk' && p.travel.minutes <= maxMin && p.lat) + .slice(0, n); +const pickAny = (key: string, n: number): Place[] => ((T.places[key] ?? []) as Place[]).filter((p) => p.lat).slice(0, n); + +const hhmm = (m: number) => `${String(Math.floor(m / 60) % 24).padStart(2, '0')}:${String(m % 60).padStart(2, '0')}`; +function buildRoute(startMin: number, stops: Array<{ p: Place | null; label: string; stay: number; note: string }>) { + let t = startMin; + const out: any[] = []; + stops.forEach((s, i) => { + const move = i === 0 ? 0 : (s.p?.travel?.minutes ?? 5); + t += move; + const from = t; + t += s.stay; + out.push({ ...s, moveMin: move, from: hhmm(from), to: hhmm(t), lat: s.p?.lat ?? oLat, lng: s.p?.lng ?? oLng }); + }); + return { stops: out, total: t - startMin, from: hhmm(startMin), to: hhmm(t) }; +} +const clinicStop = (label: string, stay: number, note: string) => ({ p: null, label, stay, note }); + +const ROUTES = [ + { + id: 'near', title: 'The day of a check-up', who: 'When you come back to the clinic often', + blurb: 'Everything within a short walk. You do not need a taxi.', + route: buildRoute(15 * 60, [ + clinicStop(clinic, 40, 'Your appointment ends here.'), + ...pick('restaurant', 10, 1).map((p) => ({ p, label: p.title, stay: 50, note: firstSentence(p.overview, 90) })), + ...pick('wellness', 12, 1).map((p) => ({ p, label: p.title, stay: 60, note: firstSentence(p.overview, 90) })), + ]), + }, + { + id: 'short', title: 'A short outing', who: 'When you can walk a little further', + blurb: 'Still close, but out of the block.', + route: buildRoute(13 * 60, [ + clinicStop(clinic, 20, 'Start from the clinic.'), + ...pickAny('shopping', 1).map((p) => ({ p, label: p.title, stay: 60, note: firstSentence(p.overview, 90) })), + ...pickAny('restaurant', 2).slice(1, 2).map((p) => ({ p, label: p.title, stay: 60, note: firstSentence(p.overview, 90) })), + ]), + }, + { + id: 'city', title: 'When you can travel', who: 'Later in your stay', + blurb: 'Sights across the city. Expect to take a taxi or the subway.', + route: buildRoute(10 * 60, [ + clinicStop(clinic, 10, 'Set off from the clinic.'), + ...pickAny('attraction', 2).map((p) => ({ p, label: p.title, stay: 70, note: firstSentence(p.overview, 90) })), + ...pickAny('culture', 1).map((p) => ({ p, label: p.title, stay: 70, note: firstSentence(p.overview, 90) })), + ]), + }, +].filter((r) => r.route.stops.length > 1); + +/* 좌표를 그대로 그린 미니 지도. 외부 지도 라이브러리를 부르지 않는다. */ +function miniMap(stops: any[]) { + const W = 640, H = 200, PAD = 26; + const lats = stops.map((s) => s.lat), lngs = stops.map((s) => s.lng); + const [la0, la1] = [Math.min(...lats), Math.max(...lats)]; + const [ln0, ln1] = [Math.min(...lngs), Math.max(...lngs)]; + const sx = (ln: number) => (ln1 - ln0 < 1e-6 ? W / 2 : PAD + ((ln - ln0) / (ln1 - ln0)) * (W - PAD * 2)); + const sy = (la: number) => (la1 - la0 < 1e-6 ? H / 2 : H - PAD - ((la - la0) / (la1 - la0)) * (H - PAD * 2)); + return stops.map((s, i) => ({ x: +sx(s.lng).toFixed(1), y: +sy(s.lat).toFixed(1), n: i + 1, label: s.label })); +} + +const allPlaces: Array = GROUPS.flatMap((g) => + ((T.places[g.key] ?? []) as Place[]).map((p) => ({ ...p, cat: g.key }))); const ld = [ { '@type': 'WebPage', '@id': `${site}/en/stay#page`, name: `Your stay near ${clinic}`, url: `${site}/en/stay`, inLanguage: 'en', isPartOf: { '@id': `${site}/#website` }, about: { '@id': `${f.url}/#clinic` }, publisher: { '@type': 'Organization', name: SITE_NAME, url: site } }, @@ -38,80 +134,270 @@ const ld = [ --- -
+
For international patients

Your Stay in Seoul

-

- Where to stay, eat and rest around {clinic}. - Everything below is listed by distance from the clinic at {f.address?.fullEn || f.address?.full}. - Addresses and names come from the Korea Tourism Organization, not from us. - For the clinic's own address, hours and phone, see Clinic information. +

+ Around {clinic}. Everything below is measured from the clinic at {f.address?.fullEn || f.address?.full}. + Names, photographs and descriptions come from the Korea Tourism Organization. + For the clinic's own hours and phone, see Clinic informationKO.

-

Before you use this page

-
- - - -
Reference point{clinic} — {T.meta.origin.lat}, {T.meta.origin.lng}
SourceKorea Tourism Organization, TourAPI EngService2 — collected {T.meta.fetchedAt.slice(0, 10)}
Search radiusStay and food 5 km · sights, culture, shopping 10 km · festivals {T.meta.festivalRadiusKm} km
+ + -

Planning your days

-

- How many days each stage lasts depends on your procedure, and only your doctor can tell you that. - The stages below are defined by distance from the clinic, nothing else. -

- {recoveryStages - ?

{recoveryStages}

- :

The day-by-day schedule is pending confirmation by {clinic}. Ask at your consultation.

} -
- - - -
StageDistance from clinicWhat fits here
Frequent visitswithin 1 kmHotels and food you can reach on foot
Short outings1 – 3 kmRestaurants, spas
Around the city3 – 10 kmSights, culture, shopping
+ + - {GROUPS.map((g) => { - const items = (T.places[g.key] ?? []) as any[]; - return ( -
-

{g.label}

-

{g.blurb}

- {g.key === 'restaurant' && ( - dietGuide - ?

What {clinic} advises after surgery. {dietGuide}

- :

What you may eat after surgery is a medical question. {clinic} has not yet published English guidance, so we do not mark any restaurant as suitable. Please ask at your consultation.

- )} - {items.length === 0 - ?

No English listings within this radius.

- :
- {items.map((p) => )} -
NameDistanceAddress
{p.title}{dist(p.distanceM)}{p.address}
} -
- ); - })} + +
+
+

Around the clinic

+ Updated {T.meta.fetchedAt.slice(0, 10)} +
+

{T.filters.total} places, sorted by how long they take to reach on foot.

-

Festivals and events while you are here

-

Currently running or starting soon, within {T.meta.festivalRadiusKm} km of the clinic.

- {T.festivals.length === 0 - ?

No listings.

- :
- {T.festivals.map((e: any) => )} -
EventDatesDistanceWhere
{e.title}{dt(e.startDate)} – {dt(e.endDate)}{e.distanceKm} km{e.address}
} +
+ + + + + +
-

What this page does not tell you

-
    -
  • No ratings, review counts or opening hours. The tourism data does not carry them, and we do not guess.
  • -
  • No claim that any restaurant suits your recovery. That is for {clinic} to say.
  • -
  • English tourism listings around Gangnam are thin. Some categories hold only a handful of entries.
  • -
  • We are not a travel agency and take no booking or commission. Links and names are for reference.
  • -
+ {GROUPS.map((g) => { + const items = allPlaces.filter((p) => p.cat === g.key); + if (!items.length) return null; + return ( +
+

{g.label} {g.note}

+
+ {items.map((p) => ( +
+
+ {p.image ? : {shortName(p.title)}} + {p.travel && {p.travel.label} {p.distanceM! < 1000 ? `${p.distanceM} m` : `${(p.distanceM! / 1000).toFixed(1)} km`}} +
+
+

{p.title}

+

{firstSentence(p.overview) || 'No description provided by the tourism data.'}

+

{p.address}

+ {p.homepage + ? Official site ↗ + : Open in search ↗} +
+
+ ))} +
+
+ ); + })} +

Source · Korea Tourism Organization TourAPI. Walking time is estimated at 80 m per minute and is not a routed distance.

+
-

{has(reservationUrl) && Book a consultation with {clinic}}

-

{f.sideEffectNoticeEn || f.sideEffectNotice}

+ +
+

Festivals and events

+

{T.festivals.length} events within {T.meta.festivalRadiusKm} km, grouped by season. Right now it is {nowSeason}.

+
+ + {SEASONS.map((s) => { + const n = T.festivals.filter((e: any) => e.season === s.key).length; + return n ? : null; + })} +
+
+ {T.festivals.map((e: any) => ( +
+
+ {e.image ? : {shortName(e.title)}} + {MONTHS[e.month] ?? ''} +
+
+

{e.title}

+

{dt(e.startDate)} – {dt(e.endDate)} · {e.travel ? e.travel.label : `${e.distanceKm} km`}

+

{firstSentence(e.overview) || 'No description provided by the tourism data.'}

+

{e.address}

+ Open in search ↗ +
+
+ ))} +
+

Source · Korea Tourism Organization TourAPI. Dates can change at the organiser's discretion.

+
+ + +
+

Shaping your days

+

+ Three routes built from the places above. The clock times assume an appointment ending at the hour shown, and are an example, not your schedule. +

+ {Sx.recoveryStagesEn + ?

What {clinic} advises. {Sx.recoveryStagesEn}

+ :

Which of these you can do, and on which day, is a medical question. {clinic} has not yet published English guidance. Ask at your consultation.

} + + {ROUTES.map((r) => { + const pins = miniMap(r.route.stops); + return ( +
+
+
+

{r.title}

+

{r.who}

+
+
{r.route.from}–{r.route.to} · {Math.floor(r.route.total / 60)}h {r.route.total % 60}m
+
+

{r.blurb}

+ + + `${p.x},${p.y}`).join(' ')} fill="none" stroke="#C5CBF5" stroke-width="2" stroke-dasharray="5 4" /> + {pins.map((p) => ( + {p.n} + ))} + +

Positions are drawn from coordinates, to scale with each other. Not a street map.

+
    + {r.route.stops.map((s: any, i: number) => ( +
  1. + {i > 0 &&
    ↓ {s.moveMin} min
    } +
    + {i + 1} +
    +
    {s.from}–{s.to}
    +

    {s.label}

    +

    {s.note}

    +
    +
    +
  2. + ))} +
+
+ ); + })} +
+ +
+

What this page does not tell you

+
    +
  • No ratings, review counts or opening hours. The tourism data does not carry them.
  • +
  • No claim that any place suits your recovery. That is for {clinic} to say.
  • +
  • English tourism listings around Gangnam are thin. Only {T.filters.walk5} places sit within a five minute walk, and {T.filters.drive} of {T.filters.total} need a car.
  • +
  • We are not a travel agency, take no booking and no commission.
  • +
+

+ {has(f.urlEn) && Book a consultation in English} +

+

{f.sideEffectNoticeEn || f.sideEffectNotice}

+
+ + diff --git a/supporters/src/styles/global.css b/supporters/src/styles/global.css index e3269de..6409470 100644 --- a/supporters/src/styles/global.css +++ b/supporters/src/styles/global.css @@ -277,3 +277,189 @@ td { color: var(--slate-700); } font-size: 0.92rem; } .notice-pending { font-size: 0.82rem; opacity: 0.75; } + + +/* 영문 화면에서 한국어 페이지로 가는 링크에 붙인다. 눌러보고 알게 하지 않는다. */ +.lang-tag { + display: inline-block; + margin-left: 0.28em; + padding: 0 0.3em; + border: 1px solid currentColor; + border-radius: 3px; + font-size: 0.62em; + font-weight: 600; + letter-spacing: 0.04em; + vertical-align: 0.18em; + opacity: 0.55; +} + +/* 언어 전환. 머리말 오른쪽에 하나만 둔다. 항목마다 표시하지 않는다. */ +.langswitch { + display: inline-flex; + align-items: center; + border: 1px solid var(--line, #E2E8F0); + border-radius: 999px; + overflow: hidden; + margin-right: 0.7rem; + flex-shrink: 0; +} +.langswitch a { + padding: 0.26rem 0.62rem; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.05em; + color: var(--slate-500, #64748B); + text-decoration: none; + line-height: 1.45; + transition: background 0.15s, color 0.15s; +} +.langswitch a:hover { background: var(--near, #F4F6FB); color: var(--primary-900, #0A1128); } +.langswitch a.on { + background: var(--primary-900, #0A1128); + color: #fff; +} +.langswitch a.on:hover { background: var(--primary-900, #0A1128); color: #fff; } + +/* ── /en/stay ── */ +.stay { padding-bottom: 4rem; } +.stay .lede { color: var(--slate-600, #475569); margin-top: 0.6rem; } +.stay section { margin-top: 3.4rem; } +.stay .sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; } +.stay .sec-head h2 { margin: 0; } +.stay .upd { font-size: 0.8rem; color: var(--slate-500, #64748B); } +.stay .sub { color: var(--slate-600, #475569); margin: 0.4rem 0 1rem; } +.stay .src { font-size: 0.84rem; color: var(--slate-500, #64748B); margin-top: 1rem; } +.stay .chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.2rem 0 1.6rem; } +.stay .chip { + border: 1px solid var(--line, #E2E8F0); background: #fff; border-radius: 999px; + padding: 0.36rem 0.85rem; font: inherit; font-size: 0.86rem; color: var(--slate-600, #475569); + cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; +} +.stay .chip b { font-weight: 700; opacity: 0.55; margin-left: 0.25em; } +.stay .chip:hover { border-color: var(--primary-900, #0A1128); } +.stay .chip.on { background: var(--primary-900, #0A1128); border-color: var(--primary-900, #0A1128); color: #fff; } +.stay .chip.on b { opacity: 0.7; } +.stay .grp { margin-bottom: 2.2rem; } +.stay .grp h3 { margin: 0 0 0.9rem; } +.stay .grp h3 small { font-weight: 400; font-size: 0.82rem; color: var(--slate-500, #64748B); margin-left: 0.45em; } +.stay .cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 1rem; } +.stay .card { + background: #fff; border: 1px solid var(--line, #E2E8F0); border-radius: 14px; + overflow: hidden; display: flex; flex-direction: column; + box-shadow: 3px 4px 12px rgba(0, 0, 0, 0.05); +} +.stay .card .thumb { position: relative; height: 148px; background: #EEF1F6; display: flex; align-items: center; justify-content: center; } +.stay .card .thumb img { width: 100%; height: 148px; object-fit: cover; display: block; } +.stay .card .nophoto { + font-size: 1.02rem; font-weight: 700; color: var(--slate-500, #64748B); + padding: 0 1rem; text-align: center; line-height: 1.35; word-break: keep-all; +} +.stay .card .badge { + position: absolute; left: 0.6rem; bottom: 0.6rem; + background: rgba(10, 17, 40, 0.82); color: #fff; border-radius: 6px; + padding: 0.18rem 0.45rem; font-size: 0.74rem; font-weight: 600; +} +.stay .card .badge em { font-style: normal; opacity: 0.7; margin-left: 0.25em; } +.stay .card .badge.mono { letter-spacing: 0.06em; } +.stay .card .body { padding: 0.85rem 0.95rem 1rem; display: flex; flex-direction: column; flex: 1; } +.stay .card h4 { margin: 0 0 0.35rem; font-size: 0.98rem; } +.stay .card .when { font-size: 0.8rem; color: var(--slate-600, #475569); margin: 0 0 0.4rem; } +.stay .card .desc { font-size: 0.86rem; color: var(--slate-600, #475569); margin: 0 0 0.5rem; } +.stay .card .addr { font-size: 0.78rem; color: var(--slate-500, #64748B); margin: 0 0 0.6rem; } +.stay .card .go { font-size: 0.82rem; margin-top: auto; } +.stay .route { border: 1px solid var(--line, #E2E8F0); border-radius: 16px; padding: 1.3rem 1.4rem; margin-bottom: 1.4rem; background: #fff; } +.stay .route-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; } +.stay .route-head h3 { margin: 0; } +.stay .route .who { font-size: 0.84rem; color: var(--slate-500, #64748B); margin: 0.15rem 0 0; } +.stay .route .clock { font-size: 0.86rem; font-weight: 600; color: var(--primary-900, #0A1128); white-space: nowrap; } +.stay .route .blurb { color: var(--slate-600, #475569); margin: 0.7rem 0 1rem; } +.stay .route .map { width: 100%; height: auto; display: block; border-radius: 12px; } +.stay .route .maphint { font-size: 0.76rem; color: var(--slate-500, #64748B); margin: 0.4rem 0 1rem; } +.stay .timeline { list-style: none; padding: 0; margin: 0; } +.stay .timeline .move { font-size: 0.8rem; color: var(--slate-500, #64748B); margin: 0.35rem 0 0.35rem 1.05rem; } +.stay .timeline .stop { display: flex; gap: 0.8rem; align-items: flex-start; } +.stay .timeline .n { + flex: none; width: 26px; height: 26px; border-radius: 50%; + background: var(--primary-900, #0A1128); color: #fff; + font-size: 0.8rem; font-weight: 700; display: grid; place-items: center; margin-top: 0.1rem; +} +.stay .timeline .stop-t { font-size: 0.8rem; color: var(--slate-500, #64748B); } +.stay .timeline h4 { margin: 0.1rem 0 0.2rem; font-size: 0.98rem; } +.stay .timeline p { margin: 0; font-size: 0.86rem; color: var(--slate-600, #475569); } +.stay .botnote { margin-top: 1.6rem; } +@media (max-width: 640px) { .cards { grid-template-columns: 1fr; } } + +/* 섹션 점프. 머리말 아래에 붙어 스크롤을 따라온다. 헤더(68px) 아래에 걸리게 top 을 맞춘다. */ +.stay .jump { + position: sticky; top: 68px; z-index: 9; + display: flex; flex-wrap: wrap; gap: 0.45rem; + margin: 1.4rem 0 2.4rem; + padding: 0.62rem 0.68rem; + background: rgba(255, 255, 255, 0.58); + backdrop-filter: blur(16px) saturate(1.5); + -webkit-backdrop-filter: blur(16px) saturate(1.5); + border: 1px solid rgba(255, 255, 255, 0.6); + border-radius: 18px; + box-shadow: 0 8px 28px rgba(10, 17, 40, 0.09), inset 0 1px 0 rgba(255, 255, 255, 0.7); +} +.stay .jump a { + display: inline-flex; align-items: center; gap: 0.42rem; + padding: 0.46rem 0.9rem; + border-radius: 999px; + font-size: 0.86rem; font-weight: 600; letter-spacing: -0.005em; + color: var(--primary-900, #0A1128); + text-decoration: none; white-space: nowrap; + background: #fff; + border: 1px solid var(--line, #E2E8F0); + box-shadow: 0 1px 2px rgba(10, 17, 40, 0.06); + transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s, border-color 0.14s, color 0.14s; +} +.stay .jump a:hover { + text-decoration: none; + transform: translateY(-1px); + border-color: #C5CBF5; + box-shadow: 0 4px 12px rgba(10, 17, 40, 0.12); +} +.stay .jump a:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(10, 17, 40, 0.08); } +.stay .jump a b { + font-weight: 700; font-size: 0.72rem; line-height: 1; + padding: 0.2rem 0.4rem; border-radius: 999px; + background: #EFF0FF; color: #3A3F7C; +} +/* 지금 보고 있는 섹션 */ +.stay .jump a.on { + background: linear-gradient(to right, #4F1DA1, #021341); + border-color: transparent; color: #fff; + box-shadow: 0 4px 14px rgba(79, 29, 161, 0.32); +} +.stay .jump a.on b { background: rgba(255, 255, 255, 0.22); color: #fff; } +/* 점프로 이동했을 때 제목이 스티키 바에 가리지 않게 */ +.stay section, .stay .grp { scroll-margin-top: 152px; } +@media (max-width: 640px) { + .stay .jump { top: 60px; gap: 0.35rem; padding: 0.5rem; border-radius: 14px; } + .stay .jump a { padding: 0.4rem 0.72rem; font-size: 0.8rem; } +} + +/* 필터 칩도 눌리는 것처럼 보이게 */ +.stay .chip { + box-shadow: 0 1px 2px rgba(10, 17, 40, 0.05); + transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.15s, color 0.15s, border-color 0.15s; +} +.stay .chip:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(10, 17, 40, 0.1); } +.stay .chip:active { transform: translateY(0); } +.stay .chip.on { box-shadow: 0 4px 14px rgba(10, 17, 40, 0.22); } + +/* 오늘 날씨. 값을 못 받으면 hidden 이라 아예 그려지지 않는다. */ +.stay .wx { + display: flex; align-items: center; justify-content: space-between; + gap: 1.2rem; flex-wrap: wrap; + margin-top: 1.6rem; padding: 1rem 1.2rem; + background: linear-gradient(to right, #fff3eb, #e4cfff, #f5f9ff); + border-radius: 16px; +} +.stay .wx-now { display: flex; align-items: center; gap: 0.9rem; } +.stay .wx-temp { font-family: 'Playfair Display', serif; font-size: 2.5rem; font-weight: 700; line-height: 1; color: var(--primary-900, #0A1128); } +.stay .wx-unit { font-size: 1.1rem; vertical-align: 0.9rem; margin-left: 0.06em; opacity: 0.6; } +.stay .wx-cond { font-weight: 700; color: var(--primary-900, #0A1128); } +.stay .wx-meta { font-size: 0.8rem; color: var(--slate-600, #475569); margin-top: 0.15rem; } +.stay .wx-note { margin: 0; font-size: 0.88rem; color: var(--slate-700, #334155); max-width: 30rem; } diff --git a/templates/supporters-astro/src/data/factSheet.json b/templates/supporters-astro/src/data/factSheet.json index c6e2da7..4d71fa8 100644 --- a/templates/supporters-astro/src/data/factSheet.json +++ b/templates/supporters-astro/src/data/factSheet.json @@ -9,7 +9,7 @@ "areaLabel": "", "founded": "", "representative": "", - "address": { "full": "", "street": "", "locality": "", "region": "", "postalNote": "", "navigation": "", "source": "" }, + "address": { "full": "", "fullEn": "", "postalCode": "", "fullEnSource": "", "street": "", "locality": "", "region": "", "postalNote": "", "navigation": "", "source": "" }, "phone": "", "fax": "", "kakao": "", diff --git a/templates/supporters-astro/src/data/medicalTourism.json b/templates/supporters-astro/src/data/medicalTourism.json index 6768c74..1a7e138 100644 --- a/templates/supporters-astro/src/data/medicalTourism.json +++ b/templates/supporters-astro/src/data/medicalTourism.json @@ -1,5 +1,5 @@ { - "_comment": "의료관광 연결 데이터. scripts/fetch_medical_tourism.py 가 병원 좌표로 채운다. 비어 있으면 /en/stay 는 '목록 없음'으로 표시된다. 지어내지 않는다.", + "_comment": "의료관광 연결 데이터. scripts/fetch_medical_tourism.py 가 병원 좌표로 채운다. 비어 있으면 /en/stay 는 목록 없음으로 표시된다.", "places": { "stay": [], "restaurant": [], @@ -9,6 +9,13 @@ "shopping": [] }, "festivals": [], + "filters": { + "total": 0, + "walk5": 0, + "walk15": 0, + "walkAll": 0, + "drive": 0 + }, "meta": { "source": "", "fetchedAt": "", diff --git a/templates/supporters-astro/src/layouts/Base.astro b/templates/supporters-astro/src/layouts/Base.astro index 5f9658f..51072bd 100644 --- a/templates/supporters-astro/src/layouts/Base.astro +++ b/templates/supporters-astro/src/layouts/Base.astro @@ -20,6 +20,22 @@ const isEn = lang === 'en'; const T = isEn ? { nav: [['/posts', 'Questions'], ['/videos', 'Doctors'], ['/newsroom', 'Newsroom'], ['/en/stay', 'Your Stay'], ['/about', 'About']], cta: 'Book a Consultation', supporters: 'SUPPORTERS', back: 'Back', top: 'Back to top', sample: 'This is a sample site, not yet public.' } : { nav: [['/posts', '상담 전 질문'], ['/videos', '의료진 영상'], ['/newsroom', '뉴스룸'], ['/visit', '방문 안내'], ['/about', '매체 소개']], cta: '상담 예약', supporters: '서포터즈', back: '이전 페이지', top: '맨 위로', sample: '샘플 사이트입니다. 정식 공개 전입니다.' }; + +// 언어 전환. 같은 내용의 짝이 있는 페이지만 서로 잇고, 없으면 그 언어의 입구로 보낸다. +// 영문 페이지가 늘어나면 이 표에 줄만 추가한다. +const PAIRS: Record = { '/visit': '/en/stay' }; +const KO_ENTRY = '/'; +const EN_ENTRY = '/en/stay'; +const path = (Astro.url.pathname.replace(/\.html$/, '').replace(/\/index$/, '/').replace(/\/$/, '') || '/'); +const koPair = Object.entries(PAIRS).find(([, en]) => en === path)?.[0]; +const otherHref = isEn ? (koPair ?? KO_ENTRY) : (PAIRS[path] ?? EN_ENTRY); +// 짝이 없으면 같은 글의 번역본으로 가는 것이 아니므로 그렇게 말한다. +const otherExact = isEn ? Boolean(koPair) : Boolean(PAIRS[path]); +// 영문 페이지의 예약 버튼은 병원의 외국인용 영문 사이트로 보낸다(factSheet.urlEn). +// 한국어 예약 페이지로 보내면 영어로 온 사람이 한국어 화면을 만난다. +const ctaHref = isEn + ? ((f as Record).reservationUrlEn || (f as Record).urlEn || reservationUrl || '/en/stay') + : (reservationUrl || '/visit'); // 의료광고 고지는 규정 대상이라 임의로 번역하지 않는다(의료법 56조·추천보증 심사지침). // 병원이 영문 문구를 확정해 site.json 의 sponsorNoticeEn / factSheet 의 sideEffectNoticeEn 에 넣기 전까지는 // 한국어 원문을 그대로 싣고 확인 대기임을 밝힌다. @@ -66,7 +82,12 @@ document.addEventListener('click',function(e){var a=e.target.closest&&e.target.c - {T.cta} +
+ KO + EN +
+ {T.cta} diff --git a/templates/supporters-astro/src/pages/en/stay.astro b/templates/supporters-astro/src/pages/en/stay.astro index 1601686..cf76b89 100644 --- a/templates/supporters-astro/src/pages/en/stay.astro +++ b/templates/supporters-astro/src/pages/en/stay.astro @@ -1,12 +1,19 @@ --- -// 외국인 환자용 체류 안내. 병원 좌표를 중심으로 숙박·식사·회복·관광·행사를 이동 반경 순으로 놓는다. -// 데이터는 한국관광공사 TourAPI 영문(EngService2)에서 scripts/fetch_medical_tourism.py 가 미리 수집한 -// src/data/medicalTourism.json 이다. 값을 만들지 않는다. -// - 평점·리뷰·영업시간은 TourAPI 가 주지 않아 싣지 않는다. -// - 수술 전후 식이 적합성은 의학 판단이라 병원이 확정한 문구만 싣는다(site.json dietGuideEn). -// - 회복 단계가 며칠째인지도 병원 확정값이다(site.json recoveryStagesEn). 단계는 이동 거리로만 정의한다. +// 외국인 환자용 체류 안내. 세 부분이다. +// 1. Around the clinic — 도보·차 소요 시간으로 거른 주변 장소 +// 2. Festivals — 계절로 묶은 행사 +// 3. Suggested days — 시간표와 지도가 붙은 동선 +// +// 데이터는 한국관광공사 TourAPI 영문(EngService2)에서 scripts/fetch_medical_tourism.py 가 +// 미리 수집한 src/data/medicalTourism.json 이다. 설명문은 detailCommon2 의 overview 다. +// +// 만들지 않는 것 +// - 평점·리뷰·영업시간: TourAPI 미제공. 싣지 않는다. +// - 링크: 공식 홈페이지가 있을 때만 걸고, 없으면 검색으로 보낸다. 주소를 지어내지 않는다. +// - 식이 적합성·회복 일수: 의학 판단이라 병원 확정값만 쓴다. +// - 일정의 시각: 진료 종료 시각을 가정으로 못박아 화면에 밝힌다. 병원 일정이 아니다. import Base from '../../layouts/Base.astro'; -import { fact, site as S, SITE_NAME, clinicSchema, reservationUrl, has } from '../../lib'; +import { fact, site as S, SITE_NAME, clinicSchema, has } from '../../lib'; import data from '../../data/medicalTourism.json'; const f = fact as Record; @@ -15,21 +22,110 @@ const clinic = f.shortNameEn || f.nameEn || f.shortName || 'the clinic'; const site = Astro.site!.toString().replace(/\/$/, ''); const T = data as any; -const GROUPS: Array<{ key: string; label: string; blurb: string }> = [ - { key: 'stay', label: 'Where to stay', blurb: 'Hotels and guesthouses near the clinic, for the days when visits are frequent.' }, - { key: 'restaurant', label: 'Where to eat', blurb: 'Restaurants within walking or short-ride distance.' }, - { key: 'wellness', label: 'Rest and recovery', blurb: 'Spas and jjimjilbang listed by the Korea Tourism Organization.' }, - { key: 'attraction', label: 'Places to see', blurb: 'Sights within the city, once you are able to travel further.' }, - { key: 'culture', label: 'Culture', blurb: 'Museums, theatres and halls.' }, - { key: 'shopping', label: 'Shopping', blurb: 'Department stores, markets and streets.' }, +type Place = { + id: string; title: string; address: string; image: string | null; overview: string; + homepage: string; lat: number | null; lng: number | null; distanceM: number | null; + travel: { mode: string; minutes: number; label: string } | null; +}; + +const GROUPS: Array<{ key: string; label: string; note: string }> = [ + { key: 'restaurant', label: 'Food', note: 'Restaurants and cafés' }, + { key: 'stay', label: 'Hotels', note: 'Places to sleep' }, + { key: 'wellness', label: 'Rest', note: 'Spas and jjimjilbang' }, + { key: 'attraction', label: 'Sights', note: 'Streets, parks, landmarks' }, + { key: 'culture', label: 'Culture', note: 'Museums, theatres, halls' }, + { key: 'shopping', label: 'Shopping', note: 'Stores and markets' }, ]; -const dist = (m: number | null) => (m === null ? '' : m < 1000 ? `${m} m` : `${(m / 1000).toFixed(1)} km`); -const dt = (d: string | null) => (d && d.length === 8 ? `${d.slice(0, 4)}.${d.slice(4, 6)}.${d.slice(6, 8)}` : ''); +const SEASONS = [ + { key: 'spring', label: 'Spring' }, { key: 'summer', label: 'Summer' }, + { key: 'autumn', label: 'Autumn' }, { key: 'winter', label: 'Winter' }, +]; +const MONTHS = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +const nowSeason = ['winter', 'winter', 'spring', 'spring', 'spring', 'summer', 'summer', 'summer', 'autumn', 'autumn', 'autumn', 'winter'][new Date().getMonth()]; -// 병원이 확정하기 전에는 비운다. 임의로 채우지 않는다. -const dietGuide: string = Sx.dietGuideEn || ''; -const recoveryStages: string = Sx.recoveryStagesEn || ''; +// 검색으로 보낸다. 없는 URL 을 만들지 않는다. +const searchUrl = (q: string) => `https://www.google.com/search?q=${encodeURIComponent(q + ' Seoul')}`; +// 칩은 누적 임계값으로 거른다. 카드에 이동수단과 도보 분을 실어 두면 스크립트가 판단한다. +const dt = (d: string | null) => (d && d.length === 8 ? `${MONTHS[+d.slice(4, 6)]} ${+d.slice(6, 8)}` : ''); +// 사진이 없을 때 이름을 대신 넣는다. 빈 회색칸보다 낫고, 없는 사진을 지어내지도 않는다. +const shortName = (t: string) => { + const m = t.match(/\(([^)]+)\)\s*$/); + return (m ? m[1] : t).replace(/\s*\[.*\]\s*/g, '').trim(); +}; +const firstSentence = (s: string, n = 150) => { + if (!s) return ''; + const cut = s.slice(0, n); + const stop = cut.lastIndexOf('. '); + return (stop > 60 ? cut.slice(0, stop + 1) : cut) + (s.length > n ? '…' : ''); +}; + +/* ── 동선. 실제 데이터에서 만들고, 시각은 가정임을 화면에 밝힌다. ── */ +const oLat = T.meta.origin.lat, oLng = T.meta.origin.lng; +const pick = (key: string, maxMin: number, n: number): Place[] => + ((T.places[key] ?? []) as Place[]) + .filter((p) => p.travel && p.travel.mode === 'walk' && p.travel.minutes <= maxMin && p.lat) + .slice(0, n); +const pickAny = (key: string, n: number): Place[] => ((T.places[key] ?? []) as Place[]).filter((p) => p.lat).slice(0, n); + +const hhmm = (m: number) => `${String(Math.floor(m / 60) % 24).padStart(2, '0')}:${String(m % 60).padStart(2, '0')}`; +function buildRoute(startMin: number, stops: Array<{ p: Place | null; label: string; stay: number; note: string }>) { + let t = startMin; + const out: any[] = []; + stops.forEach((s, i) => { + const move = i === 0 ? 0 : (s.p?.travel?.minutes ?? 5); + t += move; + const from = t; + t += s.stay; + out.push({ ...s, moveMin: move, from: hhmm(from), to: hhmm(t), lat: s.p?.lat ?? oLat, lng: s.p?.lng ?? oLng }); + }); + return { stops: out, total: t - startMin, from: hhmm(startMin), to: hhmm(t) }; +} +const clinicStop = (label: string, stay: number, note: string) => ({ p: null, label, stay, note }); + +const ROUTES = [ + { + id: 'near', title: 'The day of a check-up', who: 'When you come back to the clinic often', + blurb: 'Everything within a short walk. You do not need a taxi.', + route: buildRoute(15 * 60, [ + clinicStop(clinic, 40, 'Your appointment ends here.'), + ...pick('restaurant', 10, 1).map((p) => ({ p, label: p.title, stay: 50, note: firstSentence(p.overview, 90) })), + ...pick('wellness', 12, 1).map((p) => ({ p, label: p.title, stay: 60, note: firstSentence(p.overview, 90) })), + ]), + }, + { + id: 'short', title: 'A short outing', who: 'When you can walk a little further', + blurb: 'Still close, but out of the block.', + route: buildRoute(13 * 60, [ + clinicStop(clinic, 20, 'Start from the clinic.'), + ...pickAny('shopping', 1).map((p) => ({ p, label: p.title, stay: 60, note: firstSentence(p.overview, 90) })), + ...pickAny('restaurant', 2).slice(1, 2).map((p) => ({ p, label: p.title, stay: 60, note: firstSentence(p.overview, 90) })), + ]), + }, + { + id: 'city', title: 'When you can travel', who: 'Later in your stay', + blurb: 'Sights across the city. Expect to take a taxi or the subway.', + route: buildRoute(10 * 60, [ + clinicStop(clinic, 10, 'Set off from the clinic.'), + ...pickAny('attraction', 2).map((p) => ({ p, label: p.title, stay: 70, note: firstSentence(p.overview, 90) })), + ...pickAny('culture', 1).map((p) => ({ p, label: p.title, stay: 70, note: firstSentence(p.overview, 90) })), + ]), + }, +].filter((r) => r.route.stops.length > 1); + +/* 좌표를 그대로 그린 미니 지도. 외부 지도 라이브러리를 부르지 않는다. */ +function miniMap(stops: any[]) { + const W = 640, H = 200, PAD = 26; + const lats = stops.map((s) => s.lat), lngs = stops.map((s) => s.lng); + const [la0, la1] = [Math.min(...lats), Math.max(...lats)]; + const [ln0, ln1] = [Math.min(...lngs), Math.max(...lngs)]; + const sx = (ln: number) => (ln1 - ln0 < 1e-6 ? W / 2 : PAD + ((ln - ln0) / (ln1 - ln0)) * (W - PAD * 2)); + const sy = (la: number) => (la1 - la0 < 1e-6 ? H / 2 : H - PAD - ((la - la0) / (la1 - la0)) * (H - PAD * 2)); + return stops.map((s, i) => ({ x: +sx(s.lng).toFixed(1), y: +sy(s.lat).toFixed(1), n: i + 1, label: s.label })); +} + +const allPlaces: Array = GROUPS.flatMap((g) => + ((T.places[g.key] ?? []) as Place[]).map((p) => ({ ...p, cat: g.key }))); const ld = [ { '@type': 'WebPage', '@id': `${site}/en/stay#page`, name: `Your stay near ${clinic}`, url: `${site}/en/stay`, inLanguage: 'en', isPartOf: { '@id': `${site}/#website` }, about: { '@id': `${f.url}/#clinic` }, publisher: { '@type': 'Organization', name: SITE_NAME, url: site } }, @@ -38,80 +134,270 @@ const ld = [ --- -
+
For international patients

Your Stay in Seoul

-

- Where to stay, eat and rest around {clinic}. - Everything below is listed by distance from the clinic at {f.address?.fullEn || f.address?.full}. - Addresses and names come from the Korea Tourism Organization, not from us. - For the clinic's own address, hours and phone, see Clinic information. +

+ Around {clinic}. Everything below is measured from the clinic at {f.address?.fullEn || f.address?.full}. + Names, photographs and descriptions come from the Korea Tourism Organization. + For the clinic's own hours and phone, see Clinic informationKO.

-

Before you use this page

-
- - - -
Reference point{clinic} — {T.meta.origin.lat}, {T.meta.origin.lng}
SourceKorea Tourism Organization, TourAPI EngService2 — collected {T.meta.fetchedAt.slice(0, 10)}
Search radiusStay and food 5 km · sights, culture, shopping 10 km · festivals {T.meta.festivalRadiusKm} km
+ + -

Planning your days

-

- How many days each stage lasts depends on your procedure, and only your doctor can tell you that. - The stages below are defined by distance from the clinic, nothing else. -

- {recoveryStages - ?

{recoveryStages}

- :

The day-by-day schedule is pending confirmation by {clinic}. Ask at your consultation.

} -
- - - -
StageDistance from clinicWhat fits here
Frequent visitswithin 1 kmHotels and food you can reach on foot
Short outings1 – 3 kmRestaurants, spas
Around the city3 – 10 kmSights, culture, shopping
+ + - {GROUPS.map((g) => { - const items = (T.places[g.key] ?? []) as any[]; - return ( -
-

{g.label}

-

{g.blurb}

- {g.key === 'restaurant' && ( - dietGuide - ?

What {clinic} advises after surgery. {dietGuide}

- :

What you may eat after surgery is a medical question. {clinic} has not yet published English guidance, so we do not mark any restaurant as suitable. Please ask at your consultation.

- )} - {items.length === 0 - ?

No English listings within this radius.

- :
- {items.map((p) => )} -
NameDistanceAddress
{p.title}{dist(p.distanceM)}{p.address}
} -
- ); - })} + +
+
+

Around the clinic

+ Updated {T.meta.fetchedAt.slice(0, 10)} +
+

{T.filters.total} places, sorted by how long they take to reach on foot.

-

Festivals and events while you are here

-

Currently running or starting soon, within {T.meta.festivalRadiusKm} km of the clinic.

- {T.festivals.length === 0 - ?

No listings.

- :
- {T.festivals.map((e: any) => )} -
EventDatesDistanceWhere
{e.title}{dt(e.startDate)} – {dt(e.endDate)}{e.distanceKm} km{e.address}
} +
+ + + + + +
-

What this page does not tell you

-
    -
  • No ratings, review counts or opening hours. The tourism data does not carry them, and we do not guess.
  • -
  • No claim that any restaurant suits your recovery. That is for {clinic} to say.
  • -
  • English tourism listings around Gangnam are thin. Some categories hold only a handful of entries.
  • -
  • We are not a travel agency and take no booking or commission. Links and names are for reference.
  • -
+ {GROUPS.map((g) => { + const items = allPlaces.filter((p) => p.cat === g.key); + if (!items.length) return null; + return ( +
+

{g.label} {g.note}

+
+ {items.map((p) => ( +
+
+ {p.image ? : {shortName(p.title)}} + {p.travel && {p.travel.label} {p.distanceM! < 1000 ? `${p.distanceM} m` : `${(p.distanceM! / 1000).toFixed(1)} km`}} +
+
+

{p.title}

+

{firstSentence(p.overview) || 'No description provided by the tourism data.'}

+

{p.address}

+ {p.homepage + ? Official site ↗ + : Open in search ↗} +
+
+ ))} +
+
+ ); + })} +

Source · Korea Tourism Organization TourAPI. Walking time is estimated at 80 m per minute and is not a routed distance.

+
-

{has(reservationUrl) && Book a consultation with {clinic}}

-

{f.sideEffectNoticeEn || f.sideEffectNotice}

+ +
+

Festivals and events

+

{T.festivals.length} events within {T.meta.festivalRadiusKm} km, grouped by season. Right now it is {nowSeason}.

+
+ + {SEASONS.map((s) => { + const n = T.festivals.filter((e: any) => e.season === s.key).length; + return n ? : null; + })} +
+
+ {T.festivals.map((e: any) => ( +
+
+ {e.image ? : {shortName(e.title)}} + {MONTHS[e.month] ?? ''} +
+
+

{e.title}

+

{dt(e.startDate)} – {dt(e.endDate)} · {e.travel ? e.travel.label : `${e.distanceKm} km`}

+

{firstSentence(e.overview) || 'No description provided by the tourism data.'}

+

{e.address}

+ Open in search ↗ +
+
+ ))} +
+

Source · Korea Tourism Organization TourAPI. Dates can change at the organiser's discretion.

+
+ + +
+

Shaping your days

+

+ Three routes built from the places above. The clock times assume an appointment ending at the hour shown, and are an example, not your schedule. +

+ {Sx.recoveryStagesEn + ?

What {clinic} advises. {Sx.recoveryStagesEn}

+ :

Which of these you can do, and on which day, is a medical question. {clinic} has not yet published English guidance. Ask at your consultation.

} + + {ROUTES.map((r) => { + const pins = miniMap(r.route.stops); + return ( +
+
+
+

{r.title}

+

{r.who}

+
+
{r.route.from}–{r.route.to} · {Math.floor(r.route.total / 60)}h {r.route.total % 60}m
+
+

{r.blurb}

+ + + `${p.x},${p.y}`).join(' ')} fill="none" stroke="#C5CBF5" stroke-width="2" stroke-dasharray="5 4" /> + {pins.map((p) => ( + {p.n} + ))} + +

Positions are drawn from coordinates, to scale with each other. Not a street map.

+
    + {r.route.stops.map((s: any, i: number) => ( +
  1. + {i > 0 &&
    ↓ {s.moveMin} min
    } +
    + {i + 1} +
    +
    {s.from}–{s.to}
    +

    {s.label}

    +

    {s.note}

    +
    +
    +
  2. + ))} +
+
+ ); + })} +
+ +
+

What this page does not tell you

+
    +
  • No ratings, review counts or opening hours. The tourism data does not carry them.
  • +
  • No claim that any place suits your recovery. That is for {clinic} to say.
  • +
  • English tourism listings around Gangnam are thin. Only {T.filters.walk5} places sit within a five minute walk, and {T.filters.drive} of {T.filters.total} need a car.
  • +
  • We are not a travel agency, take no booking and no commission.
  • +
+

+ {has(f.urlEn) && Book a consultation in English} +

+

{f.sideEffectNoticeEn || f.sideEffectNotice}

+
+ + diff --git a/templates/supporters-astro/src/styles/global.css b/templates/supporters-astro/src/styles/global.css index e3269de..6409470 100644 --- a/templates/supporters-astro/src/styles/global.css +++ b/templates/supporters-astro/src/styles/global.css @@ -277,3 +277,189 @@ td { color: var(--slate-700); } font-size: 0.92rem; } .notice-pending { font-size: 0.82rem; opacity: 0.75; } + + +/* 영문 화면에서 한국어 페이지로 가는 링크에 붙인다. 눌러보고 알게 하지 않는다. */ +.lang-tag { + display: inline-block; + margin-left: 0.28em; + padding: 0 0.3em; + border: 1px solid currentColor; + border-radius: 3px; + font-size: 0.62em; + font-weight: 600; + letter-spacing: 0.04em; + vertical-align: 0.18em; + opacity: 0.55; +} + +/* 언어 전환. 머리말 오른쪽에 하나만 둔다. 항목마다 표시하지 않는다. */ +.langswitch { + display: inline-flex; + align-items: center; + border: 1px solid var(--line, #E2E8F0); + border-radius: 999px; + overflow: hidden; + margin-right: 0.7rem; + flex-shrink: 0; +} +.langswitch a { + padding: 0.26rem 0.62rem; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.05em; + color: var(--slate-500, #64748B); + text-decoration: none; + line-height: 1.45; + transition: background 0.15s, color 0.15s; +} +.langswitch a:hover { background: var(--near, #F4F6FB); color: var(--primary-900, #0A1128); } +.langswitch a.on { + background: var(--primary-900, #0A1128); + color: #fff; +} +.langswitch a.on:hover { background: var(--primary-900, #0A1128); color: #fff; } + +/* ── /en/stay ── */ +.stay { padding-bottom: 4rem; } +.stay .lede { color: var(--slate-600, #475569); margin-top: 0.6rem; } +.stay section { margin-top: 3.4rem; } +.stay .sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; } +.stay .sec-head h2 { margin: 0; } +.stay .upd { font-size: 0.8rem; color: var(--slate-500, #64748B); } +.stay .sub { color: var(--slate-600, #475569); margin: 0.4rem 0 1rem; } +.stay .src { font-size: 0.84rem; color: var(--slate-500, #64748B); margin-top: 1rem; } +.stay .chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.2rem 0 1.6rem; } +.stay .chip { + border: 1px solid var(--line, #E2E8F0); background: #fff; border-radius: 999px; + padding: 0.36rem 0.85rem; font: inherit; font-size: 0.86rem; color: var(--slate-600, #475569); + cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; +} +.stay .chip b { font-weight: 700; opacity: 0.55; margin-left: 0.25em; } +.stay .chip:hover { border-color: var(--primary-900, #0A1128); } +.stay .chip.on { background: var(--primary-900, #0A1128); border-color: var(--primary-900, #0A1128); color: #fff; } +.stay .chip.on b { opacity: 0.7; } +.stay .grp { margin-bottom: 2.2rem; } +.stay .grp h3 { margin: 0 0 0.9rem; } +.stay .grp h3 small { font-weight: 400; font-size: 0.82rem; color: var(--slate-500, #64748B); margin-left: 0.45em; } +.stay .cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 1rem; } +.stay .card { + background: #fff; border: 1px solid var(--line, #E2E8F0); border-radius: 14px; + overflow: hidden; display: flex; flex-direction: column; + box-shadow: 3px 4px 12px rgba(0, 0, 0, 0.05); +} +.stay .card .thumb { position: relative; height: 148px; background: #EEF1F6; display: flex; align-items: center; justify-content: center; } +.stay .card .thumb img { width: 100%; height: 148px; object-fit: cover; display: block; } +.stay .card .nophoto { + font-size: 1.02rem; font-weight: 700; color: var(--slate-500, #64748B); + padding: 0 1rem; text-align: center; line-height: 1.35; word-break: keep-all; +} +.stay .card .badge { + position: absolute; left: 0.6rem; bottom: 0.6rem; + background: rgba(10, 17, 40, 0.82); color: #fff; border-radius: 6px; + padding: 0.18rem 0.45rem; font-size: 0.74rem; font-weight: 600; +} +.stay .card .badge em { font-style: normal; opacity: 0.7; margin-left: 0.25em; } +.stay .card .badge.mono { letter-spacing: 0.06em; } +.stay .card .body { padding: 0.85rem 0.95rem 1rem; display: flex; flex-direction: column; flex: 1; } +.stay .card h4 { margin: 0 0 0.35rem; font-size: 0.98rem; } +.stay .card .when { font-size: 0.8rem; color: var(--slate-600, #475569); margin: 0 0 0.4rem; } +.stay .card .desc { font-size: 0.86rem; color: var(--slate-600, #475569); margin: 0 0 0.5rem; } +.stay .card .addr { font-size: 0.78rem; color: var(--slate-500, #64748B); margin: 0 0 0.6rem; } +.stay .card .go { font-size: 0.82rem; margin-top: auto; } +.stay .route { border: 1px solid var(--line, #E2E8F0); border-radius: 16px; padding: 1.3rem 1.4rem; margin-bottom: 1.4rem; background: #fff; } +.stay .route-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; } +.stay .route-head h3 { margin: 0; } +.stay .route .who { font-size: 0.84rem; color: var(--slate-500, #64748B); margin: 0.15rem 0 0; } +.stay .route .clock { font-size: 0.86rem; font-weight: 600; color: var(--primary-900, #0A1128); white-space: nowrap; } +.stay .route .blurb { color: var(--slate-600, #475569); margin: 0.7rem 0 1rem; } +.stay .route .map { width: 100%; height: auto; display: block; border-radius: 12px; } +.stay .route .maphint { font-size: 0.76rem; color: var(--slate-500, #64748B); margin: 0.4rem 0 1rem; } +.stay .timeline { list-style: none; padding: 0; margin: 0; } +.stay .timeline .move { font-size: 0.8rem; color: var(--slate-500, #64748B); margin: 0.35rem 0 0.35rem 1.05rem; } +.stay .timeline .stop { display: flex; gap: 0.8rem; align-items: flex-start; } +.stay .timeline .n { + flex: none; width: 26px; height: 26px; border-radius: 50%; + background: var(--primary-900, #0A1128); color: #fff; + font-size: 0.8rem; font-weight: 700; display: grid; place-items: center; margin-top: 0.1rem; +} +.stay .timeline .stop-t { font-size: 0.8rem; color: var(--slate-500, #64748B); } +.stay .timeline h4 { margin: 0.1rem 0 0.2rem; font-size: 0.98rem; } +.stay .timeline p { margin: 0; font-size: 0.86rem; color: var(--slate-600, #475569); } +.stay .botnote { margin-top: 1.6rem; } +@media (max-width: 640px) { .cards { grid-template-columns: 1fr; } } + +/* 섹션 점프. 머리말 아래에 붙어 스크롤을 따라온다. 헤더(68px) 아래에 걸리게 top 을 맞춘다. */ +.stay .jump { + position: sticky; top: 68px; z-index: 9; + display: flex; flex-wrap: wrap; gap: 0.45rem; + margin: 1.4rem 0 2.4rem; + padding: 0.62rem 0.68rem; + background: rgba(255, 255, 255, 0.58); + backdrop-filter: blur(16px) saturate(1.5); + -webkit-backdrop-filter: blur(16px) saturate(1.5); + border: 1px solid rgba(255, 255, 255, 0.6); + border-radius: 18px; + box-shadow: 0 8px 28px rgba(10, 17, 40, 0.09), inset 0 1px 0 rgba(255, 255, 255, 0.7); +} +.stay .jump a { + display: inline-flex; align-items: center; gap: 0.42rem; + padding: 0.46rem 0.9rem; + border-radius: 999px; + font-size: 0.86rem; font-weight: 600; letter-spacing: -0.005em; + color: var(--primary-900, #0A1128); + text-decoration: none; white-space: nowrap; + background: #fff; + border: 1px solid var(--line, #E2E8F0); + box-shadow: 0 1px 2px rgba(10, 17, 40, 0.06); + transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s, border-color 0.14s, color 0.14s; +} +.stay .jump a:hover { + text-decoration: none; + transform: translateY(-1px); + border-color: #C5CBF5; + box-shadow: 0 4px 12px rgba(10, 17, 40, 0.12); +} +.stay .jump a:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(10, 17, 40, 0.08); } +.stay .jump a b { + font-weight: 700; font-size: 0.72rem; line-height: 1; + padding: 0.2rem 0.4rem; border-radius: 999px; + background: #EFF0FF; color: #3A3F7C; +} +/* 지금 보고 있는 섹션 */ +.stay .jump a.on { + background: linear-gradient(to right, #4F1DA1, #021341); + border-color: transparent; color: #fff; + box-shadow: 0 4px 14px rgba(79, 29, 161, 0.32); +} +.stay .jump a.on b { background: rgba(255, 255, 255, 0.22); color: #fff; } +/* 점프로 이동했을 때 제목이 스티키 바에 가리지 않게 */ +.stay section, .stay .grp { scroll-margin-top: 152px; } +@media (max-width: 640px) { + .stay .jump { top: 60px; gap: 0.35rem; padding: 0.5rem; border-radius: 14px; } + .stay .jump a { padding: 0.4rem 0.72rem; font-size: 0.8rem; } +} + +/* 필터 칩도 눌리는 것처럼 보이게 */ +.stay .chip { + box-shadow: 0 1px 2px rgba(10, 17, 40, 0.05); + transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.15s, color 0.15s, border-color 0.15s; +} +.stay .chip:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(10, 17, 40, 0.1); } +.stay .chip:active { transform: translateY(0); } +.stay .chip.on { box-shadow: 0 4px 14px rgba(10, 17, 40, 0.22); } + +/* 오늘 날씨. 값을 못 받으면 hidden 이라 아예 그려지지 않는다. */ +.stay .wx { + display: flex; align-items: center; justify-content: space-between; + gap: 1.2rem; flex-wrap: wrap; + margin-top: 1.6rem; padding: 1rem 1.2rem; + background: linear-gradient(to right, #fff3eb, #e4cfff, #f5f9ff); + border-radius: 16px; +} +.stay .wx-now { display: flex; align-items: center; gap: 0.9rem; } +.stay .wx-temp { font-family: 'Playfair Display', serif; font-size: 2.5rem; font-weight: 700; line-height: 1; color: var(--primary-900, #0A1128); } +.stay .wx-unit { font-size: 1.1rem; vertical-align: 0.9rem; margin-left: 0.06em; opacity: 0.6; } +.stay .wx-cond { font-weight: 700; color: var(--primary-900, #0A1128); } +.stay .wx-meta { font-size: 0.8rem; color: var(--slate-600, #475569); margin-top: 0.15rem; } +.stay .wx-note { margin: 0; font-size: 0.88rem; color: var(--slate-700, #334155); max-width: 30rem; }